home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-05-07 | 136.9 KB | 4,375 lines |
- Please send us your annotations! Just email them to
- 70302.2566@compuserve.com and indicate the topic and
- the help file that your annotation refers to. Help
- us build the SDK annotation database!
-
- 1/9/97 NOTE:
- This version fixes a bug that caused some untoward
- crashes. This version also revises the logic for
- mstater.exe, and may actually work with Visual C++ 4.2,
- though I have not tried it yet.
-
- 11/21/96 NOTE:
- The win32.hlp file that ships with Borland C++ v5.01 seems
- to be missing the help topics that correspond to annotations
- #126 (AVIFileOpen) and #140 (the STGM structure).
-
- 8/29/96 NOTE:
-
- Readers have reported that mstater.exe does not work
- with Visual C++ v4.2. Unfortunately, I don't yet have
- that version of the compiler. As soon as I get it, I will
- try to modify mstater.exe to work correctly with it.
-
- 5/8/96 NOTE:
-
- The AnnTater utility mentioned below has been mutated
- to work with the InfoViewer that is integrated in
- the Visual C++ IDE. Instead of running anntater.exe,
- run mstater.exe if you want to annotate the IDE
- InfoViewer (rather than any .hlp files you may have).
- Let me know if you have problems.
-
-
- 12/1/95 NOTE:
-
- The WDJ annotation package now includes anntater.exe.
- AnnTater contains all of our annotations and you can use it
- to automatically place our annotations in your help file.
- Although I've tried to test this software in a variety of
- situations, USE IT AT YOUR OWN RISK. If you have
- annotations of your own, you may want to back up your .ann
- file before running AnnTater. To use AnnTater, follow
- these steps. If you don't have annotations of your own, the
- easiest route is to delete your .ann file each time you run
- anntater.exe on a new installment of our annotations.
-
- 1) invoke anntater.exe
- 2) select a type of help file (Windows 3.1 API or Win32 API)
- 3) if necessary, press the Locate button to specify the
- path where this helpfile exists
- 4) select one or more annotations that you want to install
- 5) press the Copy button
- 6) press Done
-
- Note that the program displays a checkmark beside
- each annotation that it believes it has successfully
- installed during the current session.
-
-
- ----------
-
- This is the Windows Developer's Journal SDK Annotation File, a
- growing collection of useful annotations for the standard online Windows
- API help file, win31wh.hlp, which is included with every Windows C++
- compiler. You can either cut and paste these annotations into your own
- SDK help file (use ALT-E-A to create a help topic annotation), or you
- can use anntater.exe to install them automatically for you.
-
- If you have a useful annotation you would like to submit to our
- collection, send it to:
-
- 70302.2566@compuserve.com
-
- If we use your annotation, you will be listed as the
- contributor. Our thanks to the dozens of readers whose
- contributions help us continue to build this database of
- useful information for the Windows programming community.
-
-
-
- Windows Developer's Journal
-
- "The Magazine for Windows Developers"
-
- Windows Developer's Journal is the monthly publication for
- advanced Windows programmers. We cover a variety of topics
- such as Windows 95 programming, NT programming device
- drivers, undocumented functions, compiler bugs, operating
- system bugs, graphics, MFC, multimedia, communications, and
- so on -- usually in the form of reusable code that you can
- use immediately (most of our code has been compiled with
- both Borland and Microsoft C/C++ compilers). In addition,
- each month contains regular features like these:
-
- * SDK Annotations
- (they appear in the magazine before they appear in this file)
- * Bug++ of the Month
- (nasty bugs in popular C++ compilers)
- * Tech Tips
- (user-submitted tips and techniques)
- * Books in Brief
- (quick looks at recent books)
- * Understanding NT
- (covers NT-specific programming issues)
-
- and more. WDJ costs $34.99/year in the US, $45/year Canada/Mexico, or
- $64/year overseas. To order a subscription, contact
-
- Miller Freeman
- P.O. Box 56565
- Boulder, CO 80322-6565
- (800) 365-1425
- (303) 678-0439
- wdsub@rdpub.com
-
- To subscribe by email or fax, include your name, address,
- phone number, MasterCard or Visa number, and expiration
- date. From CompuServe, that email address would be
- something like this:
-
- >INTERNET:wdsub@rdpub.com
-
-
- Note: Annotation #35 proved to be incorrect and was
- removed.
-
-
- Note: due to a bug in WinHelp, it is not possible to display
- or annotate the GetRgnBox topic in the Visual C++ v1.5
- version of the helpfile. This prevents #67 from being
- properly installed.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #1
- TYPE: Win3.1
- TOPIC: Dialog Boxes
- KEYWORD: Dialog Boxes
-
- If a listbox is the first control in a dialog's tab order
- and the dialog box was not created with the WS_VISIBLE
- style, the listbox does not correctly draw itself with the
- focus.
-
- Reference: p35, March 1993 Windows/DOS Developer's Journal.
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #2
- TYPE: Win3.1
- TOPIC: Property Lists
- KEYWORD: Property Lists
-
- The oft-quoted maxim that using window properties is slower
- than using class or window extra bytes (via
- GetWindowWord()/SetWindowWord()) is totally false if you use
- a global atom rather than a string to name the property.
- Properties were about 20% slower than window words under
- Windows 3.0, but under Windows 3.1 GetProp() is about 300%
- faster than GetWindowWord().
-
- Reference: p 49, March 1993 Windows/DOS Developer's Journal.
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #3
- TYPE: Win3.1
- TOPIC: WM_MOUSEMOVE (2.x)
- KEYWORD: WM_MOUSEMOVE
-
- The documentation incorrectly states that the x and y
- arguments are in screen coordinates. They are in client
- coordinates.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #4 (revised)
- TYPE: Win3.1
- TOPIC: SetWindowsHookEx (3.1)
- KEYWORD: SetWindowsHookEx
-
- SetWindowsHookEx() has a bug: using it to install a
- task-specific hook can cause various failures. The
- workaround is to pass it a module handle rather than an
- instance handle. You can obtain a module handle from
- GetModuleHandle(). If you only have the current instance
- handle and not the name of the module, use the following
- undocumented hack under Windows 3.1:
-
- GetModuleHandle(MAKELP(0,hInstance));
-
- If you #include <windowsx.h>, you can instead use the macro
- GetInstanceModule(hInstance). Under Windows NT, just pass a
- NULL to obtain the handle of the current process. Note that
- the MSDN News article on this subject has the arguments to
- MAKELP() backwards.
-
-
- Reference: MSDN News #1, 1993
- Revised by: Tom Nolan
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #5
- TYPE: Win3.1
- TOPIC: CS_BYTEALIGNWINDOW 0x2000
- KEYWORD: CS_BYTEALIGNWINDOW
-
- The documentation makes it sound like this style bit is the
- one you want for efficient bitblts. In fact, most of your
- bitblts will be to the client area of the window, not the
- non-client area, so CS_BYTEALIGNCLIENT is the style bit you
- should set if you are concerned about bitblt operation
- efficiency. Unaligned windows are slower at VGA resolution,
- but typically not an issue with higher resolution
- adapters (such as 256-color SVGA).
-
- Reference: p65, December 1993 Windows/DOS Developer's Journal.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #6
- TYPE: Win3.1
- TOPIC: CODE Module Definition Statement
- KEYWORD: CODE Module Definition Statement
-
- The documentation for the FIXED attribute is incorrect.
- Under Windows 3.1, if you mark code or data segments in your
- .exe FIXED, the loader ignores that attribute -- the
- segments will be moveable. If you mark code or data
- segments in your .dll FIXED, however, the loader will make
- them fixed and will page lock them as well. Due to the
- implementation of GlobalPageLock(), that can result in your
- segments using up precious DOS memory, eventually preventing
- Windows from spawning new applications (since each new
- application needs at least 512 bytes of DOS memory for a
- task database entry). The October 1994 Windows
- Developer's Journal provides code to allocate fixed memory
- without using up precious conventional memory.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #7
- TYPE: Win3.1
- TOPIC: WS_EX_TRANSPARENT 0x00000020L
- KEYWORD: WS_EX_TRANSPARENT
-
- Note that this bit does not really create transparent
- windows. If you create a window with this style, it is true
- that the windows below it will show through as its
- background. However, if you then move your new window, it
- will have the same background as it did in its original
- position -- blotting out whatever it is covering in its new
- position.
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #8
- TYPE: Win3.1
- TOPIC: WM_NCHITTEST (2.x)
- KEYWORD: WM_NCHITTEST
-
- You can process this message to allow the user to drag a
- window that does not have a title bar. When you receive a
- WM_NCHITTEST message and the mouse is in your client area
- (or whatever conditions you want to start the drag), just
- return HTCAPTION rather than passing the message on to
- DefWindowProc().
-
- Reference: p 37, March 1993 Windows/DOS Developer's Journal.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #9
- TYPE: Win3.1
- TOPIC: WM_TIMER (2.x)
- KEYWORD: WM_TIMER
-
- Although it sounds odd, you can use a WM_TIMER message as a
- way to kill another application, if you can obtain the
- handle of the main of the application you want to kill.
- Create a timer callback function that does nothing but pass
- its first argument (window handle) to DestroyWindow(). Then
- use PostMessage() to post (to the other app's main window) a
- WM_TIMER message that points to your callback function.
- Your timer callback will get executed in the context of the
- target application.
-
- Reference: p 64, September 1992 Windows/DOS Developer's Journal.
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #10
- TYPE: Win3.1
- TOPIC: MemoryWrite (3.1)
- KEYWORD: MemoryWrite
-
- MemoryWrite() has a bug in it: it trashes the high 16 bits
- of the EDI register (the 32-bit version of the DI register).
- The workaround is to save the register before calling
- MemoryWrite() and restore it afterward.
-
- Reference: p. 71, April 1994 Windows/DOS Developer's Journal
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #11
- TYPE: Win3.1
- TOPIC: EscapeCommFunction (2.x)
- KEYWORD: EscapeCommFunction
-
- The documentation omits one potential value for the
- nFunction parameter, although it is defined in windows.h.
- The name is GETBASEIRQ and it returns the base address of
- the COM port in the lower word and the IRQ setting in the
- high word. If the high word is -1 the port doesn't exist;
- if it is 0, the comm driver does not support this escape
- (which is the case, for example with some kinds of enhanced
- serial boards).
-
- Submitted by: Thomas Zeisluft
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #12
- TYPE: Win3.1
- TOPIC: MessageBox (2.x)
- KEYWORD: MessageBox
-
- Do not call MessageBox() from within the LibMain() of an
- implicitly-linked DLL. It will fail because the application
- will not yet have a message queue at that point, and
- MessageBox() (or anything else) cannot create its window
- when the message queue does not yet exist. Once the
- application executes its internal startup code and calls
- InitApp(), then it has a message queue and can safely call
- functions that create windows.
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #13
- TYPE: Win3.1
- TOPIC: LB_ADDSTRING (2.x)
- KEYWORD: LB_ADDSTRING
-
- If you are changing the contents of a listbox (for example,
- by adding or deleting multiple strings), you may want to
- minimize screen redrawing and maximize speed by disabling
- window redrawing during your operation. Follow these steps:
-
- 1) Send a WM_SETREDRAW with wParam equal to FALSE to the listbox.
- 2) Perform your adds or deletes.
- 3) Send a WM_SETREDRAW with wParam equal to TRUE to the listbox.
- 4) Use InvalidateRect() to force the listbox to redraw itself.
-
- Revised by V. Ramachandran
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #14
- TYPE: Win3.1
- TOPIC: RegisterWindowMessage (2.x)
- KEYWORD: RegisterWindowMessage
-
- Do you really need to register a private window message?
- Probably not, if all you need is an intra-app message number
- that does not conflict with any Windows message numbers.
- Microsoft has revised its statement about what message
- numbers are available for your private use. Microsoft now
- guarantees that you can use message numbers 0x8000 through
- 0xBFFF and they will not conflict with any system messages.
- They also claim the next SDK (Chicago?) will define WM_APP
- equal to 0x8000 in windows.h.
-
- Reference: Microsoft Knowledge Base article Q86835
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #15
- TYPE: Win3.1
- TOPIC: WM_CHAR (2.x)
- KEYWORD: WM_CHAR
-
- The documentation incorrectly claims that wParam is the
- virtual key code. In fact, it is the ASCII value of the key
- pressed. For example, pressing the '$' (ASCII 0x5B) key
- produces a wParam equal to 0x5B -- if you interpreted that
- as a virtual key code, you would incorrectly believe that
- the user had pressed VK_HOME!
-
- Submitted by: Brent Rector
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #16
- TYPE: Win3.1
- TOPIC: WinHelp (3.0)
- KEYWORD: WinHelp
-
- The documentation says that the return value is nonzero if
- WinHelp() is successful. In fact, WinHelp() only returns
- failure for systemic problems, like being unable to allocate
- global memory, or being unable to spawn winhelp.exe. If
- WinHelp() successfully passes your request to winhelp.exe,
- it returns success, period. So, for example, if the named
- help file is invalid, or you try to jump to a help topic
- that does not exist, or any number of other logical errors,
- WinHelp() still returns success.
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #17
- TYPE: Win3.1
- TOPIC: WM_ENTERIDLE (2.x)
- KEYWORD: WM_ENTERIDLE
-
- The documentation says that this messsage gets sent to your
- application's "main window". In fact, a dialog sends the
- WM_ENTERIDLE message to its own parent window, which may or
- may not happen to be your application's main window.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #18
- TYPE: Win3.1
- TOPIC: OPENFILENAME (3.1)
- KEYWORD: OPENFILENAME
-
- The documentation does not completely describe the behavior
- when selecting multiple files. To allow the user to select
- multiple files, you turn on the flag OFN_ALLOWMULTISELECT.
- If you do that and call GetOpenFileName(), and if the user then
- selects multiple files, then GetOpenFileName() will copy (into
- lpstrFile) the path, followed by a space, followed by
- space-separated filenames. For example, if the user
- selected files "fred.1" and "fred.2" from directory
- "c:\test", lpstrFile would then point to the following
- string:
-
- "c:\test fred.1 fred.2"
-
- However, the documentation does not point out that if the
- user selects only one file, then the path is not kept
- separate from the filename. Using the previous example, if
- the user selected only file "fred.1", then lpstrFile would
- point to this:
-
- "c:\test\fred.1"
-
- Submitted by Julian Templeman
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #19
- TYPE: Win3.1
- TOPIC: CreateRoundRectRgn (3.0)
- KEYWORD: CreateRoundRectRgn
-
- This function has a bug. It will produce a GP fault if the
- region rectangle is empty (either nLeftRect equals
- nRightRect, or nBottomRect equals nTopRect). About the only
- workaround is to create a wrapper function that first checks
- whether the rectangle is empty.
-
- Reference: p67, June 1994 Windows/DOS Developer's Journal^
- Submitted by Chris Mason
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #20
- TYPE: Win3.1
- TOPIC: EnableMenuItem (2.x)
- KEYWORD: EnableMenuItem
-
- When you are making changes to a window menu, the menu bar
- is not immediately updated. To force those changes (such as
- enabling/disabling menu items) to be visible right away,
- make sure you call DrawMenuBar().
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #21
- TYPE: Win3.1
- TOPIC: DrawText (2.x)
- KEYWORD: DrawText
-
- DrawText() has an off-by-one error that can result in a GP
- fault. The bug is evoked when you use pass an explicit
- string length instead of NULL-terminating the text string.
- The bug is not evoked if you use the DT_NOPREFIX flag, or if
- you NULL-terminate the text string (the easiest workaround).
-
- Reference: p53, August 1994 Windows/DOS Developer's Journal
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #22
- TYPE: Win3.1
- TOPIC: WM_MEASUREITEM (3.0)
- KEYWORD: WM_MEASUREITEM
-
- Windows supports owner-draw menus, but only popup owner-draw
- menus work correctly. If you try to create an owner-draw
- menubar for a window, Windows will not send you the
- WM_MEASUREITEM message as it should.
-
- Reference: Microsoft Knowledge Base article Q69969
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #23
- TYPE: Win3.1
- TOPIC: WINDOWPOS (3.1)
- KEYWORD: WINDOWPOS
-
- The documentation says that y is "the position of the right
- edge of the window". It is, of course, the position of the
- top edge of the window.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #24
- TYPE: Win3.1
- TOPIC: Shell Dynamic-Data Exchange Interface Overview (3.1)
- KEYWORD: Shell Dynamic-Data Exchange Interface Overview
-
- The documentation says you can use DDE to get a list of
- Program Manager groups by "issuing a request for the Group
- item." In fact, that is not the correct item name -- you
- must use 'Groups', not 'Group'.
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #25
- TYPE: Win3.1
- TOPIC: TrackPopupMenu (3.0)
- KEYWORD: TrackPopupMenu
-
- The documentation incorrectly states that you can pass the
- TPM_RIGHTBUTTON flag if you want the menu to respond to the
- right (secondary) mouse button instead of the left (primary)
- mouse button. In fact, passing TPM_RIGHTBUTTON causes the
- menu to respond to the right mouse button as well as the
- left. There is apparently no combination of bits that cause
- the menu to respond only to the right mouse button.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #26
- TYPE: Win3.1
- TOPIC: SetDlgItemText (2.x)
- KEYWORD: SetDlgItemText
-
- There is a bug in Windows that keeps SetWindowText() and
- SetDlgItemText() from working correctly when applied to an
- edit control owned by another application. Rather than
- sending a WM_SETTEXT to the edit control as they should,
- these functions directly tinker with the target control's
- internal window structure to change its title. The bug,
- then, is twofold:
-
- a) The target window is never notified that it
- needs to repaint.
- b) An edit control ignores its title, so changing
- its title does not affect the text it contains.
-
- The workaround is to use SendMessage() or PostMessage() to
- deliver a WM_SETTEXT to the target window. If you use
- PostMessage(), make sure you pass a string pointer that is
- somehow guaranteed to still be valid whenever the target
- application gets around to fetching and processing the
- message.
-
- Reference: p. 71, September 1993 Windows/DOS Developer's Journal
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #27
- TYPE: Win3.1
- TOPIC: GetMenuItemID (2.x)
- KEYWORD: GetMenuItemID
-
- The documentation says that this function returns 0 if the
- specified menu item is a separator. In fact, although the
- resource compiler implicitly assigns separators an ID of 0,
- you can assign them any 16-bit ID you like (with
- ModifyMenu(), InsertMenu(), etc.) and this function will
- return the correct ID, not just zero.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #28
- TYPE: Win3.1
- TOPIC: GetMetaFile (2.x)
- KEYWORD: GetMetaFile
-
- Most programs that write a "Windows metafile" to disk use a
- newer file format that this function does not understand.
- Most programs read and write "placeable" metafiles, a
- metafile with a 22-byte header that contains a minimum
- bounding rectangle for the figure. If you want to read in a
- metafile that may have been written by another application,
- you should open the file yourself and check the header to
- see if it is a placeable metafile. See the SDK
- documentation for a description of "placeable Windows
- metafiles".
-
- Reference: p. 43, November 1994 Windows/DOS Developer's Journal
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #29
- TYPE: Win3.1
- TOPIC: WritePrivateProfileString (3.0)
- KEYWORD: WritePrivateProfileString
-
- The documentation for WritePrivateProfileString() and the
- prototypes in windows.h, indicate that all strings passed in
- are LPCSTR (32-bit pointer to unmodifiable character
- string). However, sometimes this function writes on your
- input string anyway! For one example, if you pass in the
- string
-
- "Hello World "
-
- the function will remove the trailing spaces by writing a
- NULL byte after the 'd'. If you were passing in a constant
- string that resided in a code segment, this aberrant
- behavior could result in a GP fault. This function
- absolutely should not modify a string declared as LPCSTR,
- but since it does, beware!
-
- Submitted by Charles Leamon
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #30
- TYPE: Win3.1
- TOPIC: GetMenuState (2.x)
- KEYWORD: GetMenuState
-
- In addition to the bits noted in the documentation, this
- function also correctly returns MF_POPUP for a submenu.
- Oddly, if you located the popup by position, the
- MF_BYPOSITION flag will also be set in the returned flags,
- although it is not on when used to locate normal menu items.
- Note that some of these flags equate to zero, so you cannot
- just AND them with the returned flags to see if they are on.
- Here are the flags that equate to zero, along with the
- expression you can use to infer their presence:
-
- Zero Flag Expression to test for flag
- ============== =================================
- MF_ENABLED !(Flag&~(MF_DISABLED|MF_GRAYED))
- MF_UNCHECKED !(Flag&~MF_CHECKED)
- MF_STRING !(Flag&~(MF_BITMAP|MF_OWNERDRAW))
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #31
- TYPE: Win3.1
- TOPIC: GetWindowPlacement (3.1)
- KEYWORD: GetWindowPlacement
-
- From the documentation, you might think the following code
- would work:
-
- WINDOWPLACEMENT Info;
- GetWindowPlacement(hWnd, &Info);
-
- In fact, it won't. You must remember to initialize the
- "length" field of the structure before calling this
- function. The following code works:
-
- WINDOWPLACEMENT Info;
- Info.length = sizeof(Info);
- GetWindowPlacement(hWnd, &Info);
-
- Submitted by Pete Davis
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #32
- TYPE: Win3.1
- TOPIC: CreateCompatibleBitmap (2.x)
- KEYWORD: CreateCompatibleBitmap
-
- The description of height and width parameters states that
- these values are in bits, when actually they are in pixels.
-
- Submitted by Charles Leamon
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #33
- TYPE: Win3.1
- TOPIC: LoadCursor (2.x)
- KEYWORD: LoadCursor
-
- The documentation says that you should call DestroyCursor()
- for cursors loaded via LoadCursor(). That is wrong -- you
- should only call DestroyCursor() for cursors created with
- CreateCursor().
-
- Submitted by Charles Leamon^
- Reference: Microsoft Knowledge Base article Q84779
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #34
- TYPE: Win3.1
- TOPIC: lstrcpyn (3.1)
- KEYWORD: lstrcpyn
-
- The documentation for lstrcpyn() states that the last
- parameter (cChars) is the number of characters to be copied,
- when in fact the number of characters will be cChars-1.
- That's convenient, but it's not what it says and it's
- inconsistent with the standard ANSI C run-time function
- strncpy(), which does copy the specified count. In other
- words, unlike strncpy(), this function always
- NULL-terminates the destination string.
-
- Submitted by Charles Leamon
-
-
- ------------------------------------------------------------
-
-
- WDJ SDK Annotation #36
- TYPE: Win3.1
- TOPIC: ExitWindows (3.0)
- KEYWORD: ExitWindows
-
- The documentation is incomplete. To just terminate Windows
- and return control to DOS, pass a zero in the dwReturnCode
- parameter.
-
- Submitted by Charles Leamon^
- Reference: Microsoft Knowledge Base article Q100359
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #37
- TYPE: Win3.1
- TOPIC: OpenFile (2.x)
- KEYWORD: OpenFile
-
-
- The descriptions for OF_CANCEL and OF_PROMPT are incorrect.
- OF_CANCEL does not add a cancel button to the 'File not
- found' (OF_PROMPT) dialog. Even if it did, how would the
- caller know the user pressed the cancel button (only one
- error return is defined for OpenFile())? The OF_PROMPT
- dialog does not prompt the user to insert a diskette into
- drive A:
-
- Submitted by Charles Leamon
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #38
- TYPE: Win3.1
- TOPIC: WM_NCHITTEST (2.x)
- KEYWORD: WM_NCHITTEST
-
- The documentation claims that this message is sent to the
- window that used SetCapture() to capture mouse input. That
- is totally false. The window whose handle is passed to
- SetCapture() will never receive any WM_NCHITTEST messages
- (no matter where you move the moust) while the mouse is
- captured.
-
- Submitted by V. Ramachandran
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #39
- TYPE: Win3.1
- TOPIC: TabbedTextOut (3.0)
- KEYWORD: TabbedTextOut
-
- The documentation claims that the tab stops are in device
- units (pixels), but that is not true. The tab stops are
- treated as logical units, not device units.
-
- Submitted by Dan Miser^
- Reference: Microsoft Knowledge Base article Q113253
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #40
- TYPE: Win3.1
- TOPIC: LoadIcon (2.x)
- KEYWORD: LoadIcon
-
- The documentation says that you should call DestroyIcon()
- for cursors loaded via LoadIcon(). That is wrong -- you
- should only call DestroyIcon() for icons created with
- CreateIcon().
-
- Submitted by Charles Leamon^
- Reference: Microsoft Knowledge Base article Q84779
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #41
- TYPE: Win3.1
- TOPIC: COMPAREITEMSTRUCT (3.0)
- KEYWORD: COMPAREITEMSTRUCT
-
- Note that Windows has to send a WM_COMPAREITEM message when
- a new item is added to the list, in order to determine its
- correct position. That means it does not know the position
- of the new item yet, so (contrary to the documentation) the
- itemID2 field in this structure will be -1 -- do not assume
- it will be a legal index value.
-
- Submitted by V. Ramachandran
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #42
- TYPE: Win3.1
- TOPIC: GetProcAddress (2.x)
- KEYWORD: GetProcAddress
-
- In attempting to locate the named function in the target
- module, GetProcAddress() converts the function name to
- uppercase and then performs a case-sensitive search. That
- means that GetProcAddress() cannot locate functions exported
- with names containing lowercase characters. Normally,
- that's not a problem, as the __pascal calling sequence
- forces uppercase names. However, depending on the compiler
- and linker tools and options you use, it is possible to
- export __cdecl calling sequence functions with lowercase
- characters, resulting in a function that GetProcAddress()
- cannot locate.
-
- Submitted by Keith Bluestone
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #43
- TYPE: Win3.1
- TOPIC: SetScrollRange (2.x)
- KEYWORD: SetScrollRange
-
- The documentation says you can use this function to hide or
- show standard scroll bars, but does not tell you how!
- Basically, if you specify the same value for both the
- minimum (nMin) and maximum (nMax) scrolling positions, the
- function will hide the scroll bar. If the two positions are
- not equal, the function will display the scroll bar.
-
- Submitted by Paul Bonneau
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #44
- TYPE: Win3.1
- TOPIC: LoadLibrary (2.x)
- KEYWORD: LoadLibrary
-
- If LoadLibrary() cannot find the library, it may display an
- error message to the user, depending upon the state of
- Windows' "error mode". If you want to handle that case
- yourself and make sure Windows does not display the error
- message, see the documentation for the function
- SetErrorMode(). For example, the following code attempts to
- load the library ctl3d.dll, but does not emit an error
- message if it is not found.
-
- HINSTANCE Ctl3d;^
- UINT OldFlag = SetErrorMode(SEM_NOOPENFILEERRORBOX);^
- Ctl3d = LoadLibrary("ctl3d.dll");^
- SetErrorMode(OldFlag); // restore previous mode^
- if(Ctl3d <= HINSTANCE_ERROR)^
- // LoadLibrary() failed for some reason^
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #45
- TYPE: Win3.1
- TOPIC: LoadLibrary (2.x)
- KEYWORD: LoadLibrary
-
-
- The documentation claims this function returns an error code
- of 0 if "System was out of memory, executable file was
- corrupt, or relocations were invalid". However, if a
- library's LibMain() function returns 0 (signifying some
- logical error during initialization), LoadLibrary() also
- returns 0. Therefore, do not assume that a 0 error code
- means the system was out of memory or that the module was
- corrupt in some way.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #46
- TYPE: Win3.1
- TOPIC: DdeClientTransaction (3.1)
- KEYWORD: DdeClientTransaction
-
- The documentation does not say so, but the cbData argument
- (length of data) must include the NULL byte if the data is a
- string. In other words, if lpvData is a string, cbData must
- be set to strlen(lpvData)+1. Otherwise, bad things may
- happen in DDEML when you perform an XTYP_POKE or
- XTYP_EXECUTE.
-
- Submitted by Mark Reha^
- Reference: Microsoft Knowledge Base article Q107387.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #47
- TYPE: Win3.1
- TOPIC: WinHelp (3.0)
- KEYWORD: WinHelp
-
- The WinHelp() API function normally allows one to execute
- macros, jumps, popups, and so on. However, if WinHelp was
- started with WinExec() (i.e. from Program Manager or File
- Manager) instead of the WinHelp() API function, you will not
- be able to execute macros or jumps on that help file without
- starting up a second instance of the help file using the
- WinHelp() API function.
-
- There is one way around this. You can create a DLL with an
- LDLLHandler that gets the callback address for the FAPI()
- function from WinHelp. FAPI() has the same parameters as
- the WinHelp() API function except that the first parameters
- (HWND) is not in FAPI() (so FAPI() only has 3 parameters).
- The FAPI() function will allow you to execute macros, jumps,
- popups, etc regardless of how WinHelp was launched. For
- more information, get the Windows Help Authors Guide from
- the MSDN CD-ROM or see Jim Mischel's book "The Developer's
- Guide to WINHELP.EXE".
-
- Submitted by Pete Davis
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #48
- TYPE: Win3.1
- TOPIC: _fpmath (2.x)
- KEYWORD: _fpmath
-
- When setting the handler for coprocessor error exceptions
- (function 3), the documentation incorrectly says you should
- place the address of your exception handler in DS:AX. The
- correct registers to use for this 32-bit address are DX:AX.
-
- Submitted by Manfred Keul
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #49
- TYPE: Win3.1
- TOPIC: VerQueryValue (3.1)
- KEYWORD: VerQueryValue
-
- Amazingly, even though the second parameter to this function
- is declared const (LPCSTR), VerQueryValue() modifies that
- string anyway! Apparently the code replaces a '\' in your
- string with a NULL byte temporarily and then puts it back.
- This is a bug. For example, suppose you use a compiler
- option that places constant strings in read-only code
- segments (for Microsoft, "/Gf"; for Borland "-dc"). In that
- case, passing such a constant string as the second argument
- to this function results in a GP fault.
-
- Submitted by David Lowndes
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #50
- TYPE: Win3.1
- TOPIC: GetProfileString (2.x)
- KEYWORD: GetProfileString
-
- This applies to both GetProfileString() and
- GetPrivateProfileString(). If the default value for these
- functions contains trailing blanks and the default value is
- used because the key did not appear in the INI file, Windows
- will null-terminate the string (even though it is declared
- const!) at the first trailing blank. If that string is a
- literal string and the code is compiled with some
- optimizations then the string will end up in a code segment,
- resulting in a GPF when the API function attempts to modify
- it.
-
- GetProfileString() and GetPrivateProfileString() also strip
- out any leading spaces, and any leading and trailing quotes
- (single or double quotes).
-
- Submitted by Michael E. Kropp.^
- Revised by Kai Riihioja
-
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #50
- TYPE: Win3.1
- TOPIC: GetPrivateProfileString (2.x)
- KEYWORD: GetPrivateProfileString
-
- This applies to both GetProfileString() and
- GetPrivateProfileString(). If the default value for these
- functions contains trailing blanks and the default value is
- used because the key did not appear in the INI file, Windows
- will null-terminate the string (even though it is declared
- const!) at the first trailing blank. If that string is a
- literal string and the code is compiled with some
- optimizations then the string will end up in a code segment,
- resulting in a GPF when the API function attempts to modify
- it.
-
- GetProfileString() and GetPrivateProfileString() also strip
- out any leading spaces, and any leading and trailing quotes
- (single or double quotes).
-
- Submitted by Michael E. Kropp.^
- Revised by Kai Riihioja
-
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #51
- TYPE: Win3.1
- TOPIC: GetTickCount (2.x)
- KEYWORD: GetTickCount
-
- GetTickCount() may return units of milliseconds, but its
- resolution is much worse than one millisecond under Windows
- 3.1. For more accurate timings, call the function
- timeGetTime(), which is defined in mmsystem.h.
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #52
- TYPE: Win3.1
- TOPIC: GetWinFlags (3.0)
- KEYWORD: GetWinFlags
-
- GetWinFlags() can also tell you if your 16-bit Windows 3.1
- application is running under Windows NT:
-
- if(GetWinFlags() & 0x04000)^
- // then we are running under Windows NT^
-
- Submitted by Paula Tomlinson.^
- Reference: "The Ultimate Windows Version Detector",
- Windows/DOS Developer's Journal, February 1995.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #53
- TYPE: Win3.1
- TOPIC: KillTimer (2.x)
- KEYWORD: KillTimer
-
- Under at least one condition, KillTimer() does not remove a
- pending WM_TIMER message from the message queue as
- documented. First, understand that Windows just sets a bit
- when a timer fires; it does not generate a WM_TIMER message
- at that time. A timer message is secretly added to your
- input queue when you call GetMessage() or PeekMessage() and
- a timer event is pending and no other messages are in the
- queue.
-
- If you are using a PeekMessage() call with the PM_NOREMOVE
- flag and if the timer bit is on at that point, PeekMessage()
- will place a WM_TIMER message in the queue, but won't remove
- it. If you then call KillTimer(), it will ensure the timer
- bit is off but won't remove the WM_TIMER message. The next
- call to GetMessage() or PeekMessage() returns this WM_TIMER
- message. One workaround is to use code like this to
- terminate a timer:
-
- KillTimer (hWnd, ID);^
- if (LOWORD (GetQueueStatus (QS_TIMER)) & QS_TIMER)^
- PeekMessage (&msg, hWnd, WM_TIMER, WM_TIMER, PM_REMOVE);^
-
- Submitted by Mike Mast.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #54
- TYPE: Win3.1
- TOPIC: DEVMODE (3.0)
- KEYWORD: DEVMODE
-
- The documentation claims that DMCOLOR_COLOR is defined to be
- 1 and DMCOLOR_MONOCHROME is defined to be 2. In fact, if
- you look in print.h you discover that the reverse is true.
-
- Submitted by Bill Liu.
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #55
- TYPE: Win3.1
- TOPIC: EN_CHANGE (2.x)
- KEYWORD: EN_CHANGE
-
- The documentation implies this notification only arises from
- actions by the user. In fact, this notification also arises
- from programmatic changes, such as from sending a WM_SETTEXT
- message to the edit control, or using SetWindowText() (which
- sends a WM_SETTEXT message). Not knowing this, you might
- code an EN_CHANGE handler that attempts to modify the edit
- control text, resulting in another EN_CHANGE notification --
- an infinite loop!
-
- Submitted by Scott Smith.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #56
- TYPE: Win3.1
- TOPIC: EnumFonts (2.x)
- KEYWORD: EnumFonts
-
- The 3.1 documentation for this function specifies that the
- third argument is of type FONTENUMPROC. This was true in
- previous versions, but in 3.1 this call is deprecated in
- favour of the new EnumFontFamilies() API function. The
- definition of the FONTENUMPROC type has been updated to take
- a NEWTEXTMETRIC parameter, and therefore no longer quite
- matches the prototype specified for EnumFonts. Microsoft
- provids a new type, OLDFONTENUMPROC, which corresponds to
- the STRICT definition of EnumFonts in windows.h, but this is
- not reflected in the documentation. In other words, if you
- compile with STRICT defined for Windows 3.1 and want to use
- EnumFonts(), make sure the third parameter is of type
- OLDFONTENUMPROC.
-
- Submitted by David W. Gillett.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #57
- TYPE: Win3.1
- TOPIC: PtInRect (2.x)
- KEYWORD: PtInRect
-
- There is no mention of this, but the rectangle MUST be
- normailized before this function is called. In other words,
- you have to make sure that lprc->right is greater than
- lprc->left, and that lrpc->bottom is greater than lrpc->top.
- Otherwise, the point will never be considered inside of the
- rectangle. By contrast, the function RectInRegion() does
- accept and correctly handle all rectangles, whether
- normalized or not.
-
- Submitted by Peter Ritchie.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #58
- TYPE: Win3.1
- TOPIC: SetTimer (2.x)
- KEYWORD: SetTimer
-
- The documentation makes it sound like Windows either posts a
- message (if you supply no callback function) or else calls
- your callback function directly when the timer expires. In
- fact, when the timer fires, Windows sets a bit in your
- message queue which gets transformed into a WM_TIMER message
- by either GetMessage() or PeekMessage() when they find no
- other messages in the input queue. The WM_TIMER message
- contains the address of your callback function (if any),
- which will be called by DefWindowProc() after the message is
- dispatched to your window. The key point here is that the
- timers created by SetTimer() are always message based
- (Windows does not call your timer procedure asynchronously)
- and of a lower priority than any other Windows message.
-
- Submitted by Alan M. Carroll.
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #59
- TYPE: Win3.1
- TOPIC: lstrcpy (2.x)
- KEYWORD: lstrcpy
-
- Believe it or not, this function (and apparently other
- similar functions) examine the limit of the selector of the
- output string, and even attempt to silently recover if the
- operation causes a GP fault. As a consequence, you should
- not count on this function being a real speed demon.
-
- Submitted by Vivek Venugopalan
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #60
- TYPE: Win3.1
- TOPIC: GetModuleFileName (2.x)
- KEYWORD: GetModuleFileName
-
- Windows 3.1 has a bug that causes this function to sometimes
- return relative paths instead of absolute (fully qualified)
- paths.This error occurs if a relative path is specified in
- the PATH variable, and the DLL is implicitly loaded from
- this directory. For example, if the PATH variable is:
-
- PATH=C:\DOS;D:.;C:\UTILS
-
- and an application running from any other directory but
- "D:.", loads a DLL (test.dll) in "D:." implicitly (since it
- is in the path), then a call to GetModuleFileName() with the
- DLL instance will return "D:.\test.dll".
-
- Submitted by V. Ramachandran
- Reference: MSKB PSS ID Number: Q85330.
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #61
- TYPE: Win3.1
- TOPIC: CB_GETDROPPEDCONTROLRECT (3.1)
- KEYWORD: CB_GETDROPPEDCONTROLRECT
-
- The documentation claims that this function retrieves the
- screen coordinates of the listbox portion of a combo box.
- In fact, it retrieves the screen coordinates of the
- rectangle that encloses the ENTIRE combo box in its
- dropped-down state. That means the rectangle retrieved is
- both bit taller and a bit wider than the rectangle that the
- help file claims is returned.
-
- Submitted by V. Ramachandran
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #62
- TYPE: Win3.1
- TOPIC: NotifyUnRegister (3.1)
- KEYWORD: NotifyUnRegister
-
- As the documentation says, you can set the htask argument to
- NULL to refer to the current task. This is probably not a
- good practice, however. If more than one application can
- load your DLL, then there is typically some scenario under
- which the task that you called NotifyRegister() for has died
- before you call NotifyUnRegister(), in which case passing
- NULL would refer to the wrong task. It's probably safer to
- explicitly store that task that was passed to
- NotifyRegister() and make sure you pass the same task to
- NotifyUnregister().
-
- Submitted by Paul Dolphin.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #63
- TYPE: Win3.1
- TOPIC: CreateCompatibleDC (2.x)
- KEYWORD: CreateCompatibleDC
-
- You might think from the name that this function returns a
- device context whose attributes are the same as the source
- device context. In fact, attributes such as the mapping
- mode will be set to their defaults (e.g., the mapping mode
- will always be MM_TEXT) in the returned device context, not
- to the attribute values of the source device context.
-
- Submitted by Stuart Patterson^
- Reference: p. 624, "Programming Windows 3.1, 3rd Edition",
- by Charles Petzold
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #64
- TYPE: Win3.1
- TOPIC: Device Contexts
- KEYWORD: Device Contexts
-
- The help file says CreateCompatibleDC() creates a device
- context that "has the same attributes" as the source device
- context. In fact, the device context's attributes (such as
- mapping mode) will have their default values, no matter what
- value they had in the source device context.
-
- Submitted by Stuart Patterson^
- Reference: p. 624, "Programming Windows 3.1, 3rd Edition",
- by Charles Petzold
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #65
- TYPE: Win3.1
- TOPIC: UngetCommChar (2.x)
- KEYWORD: UngetCommChar
-
- Do not use this function under Windows 3.1 -- it causes lost
- characters or even GP faults!
-
- Submitted by Manfred Keul.^
- Reference: Microsoft Knowledge Base article Q100183.
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #66
- TYPE: Win3.1
- TOPIC: TabbedTextOut (3.0)
- KEYWORD: TabbedTextOut
-
- If a tab character is the last character in the string, then
- all of the area to the next tab stop is filled with the
- current background color. This may or may not be the
- behavior you want in any given situation.
-
- Submitted by Tim English.
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #67
- TYPE: Win3.1
- TOPIC: GetRgnBox (3.0)
- KEYWORD: GetRgnBox
-
- The documentation claims GetRgnBox() returns COMPLEXREGION
- when the region has overlapping borders. In fact,
- GetRgnBox() apparently returns COMPLEXREGION if the region
- is simply non-rectangular, whether overlapping borders are
- involved or not.
-
- Submitted by Jason Douglas.
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #68
- TYPE: Win3.1
- TOPIC: DRAWITEMSTRUCT (3.0)
- KEYWORD: DRAWITEMSTRUCT
-
- The itemID field in this structure is set to a negative value
- for an empty listbox or combobox. Watch out, though -- since
- this field is defined to be unsigned (UINT), a statement like
- this:
-
- if(lpdis->itemID >= 0) // if listbox not empty^
- // ... some code^
-
- will always evaluate true. To check for an empty listbox or
- combobox, either cast the field to int or check the high bit:
-
- if( (int) lpdis->itemID >= 0) // this works correctly^
- //... some code^
-
- Submitted by Aaron O'Neil.
-
-
- ------------------------------------------------------------
-
-
- WDJ SDK Annotation #69
- TYPE: Win3.1
- TOPIC: DDEDATA (2.x)
- KEYWORD: DDEDATA
-
- In this help topic, the description for the fResponse field
- actually describes the fAckReq field, and vice versa.
-
- Submitted by Sudhir Menon.^
- Reference: Microsoft Knowledge Base article Q93372.
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #70
- TYPE: Win3.1
- TOPIC: EnableCommNotification (3.1)
- KEYWORD: EnableCommNotification
-
- Due to bugs in Windows 3.1, you will probably want to always set
- both cbWriteNotify and cbOutQueue to -1, thus disabling the
- CN_TRANSMIT and CN_RECEIVE notifications. If you do not set
- them to -1, spurious WM_COMMNOTIFY messages can be sent,
- resulting in a system crash at higher baud rates.
-
- Submitted by Manfred Keul.^
- Reference: Microsoft Knowledge Base article Q101420.
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #71
- TYPE: Win3.1
- TOPIC: GetMsgProc (3.1)
- KEYWORD: GetMsgProc
-
- The help file fails to mention that your hook function gets
- called by PeekMessage(), not just by GetMessage(). The
- documentation also contradicts itself, saying first that wParam
- is undefined and later saying that wParam is NULL. The
- Microsoft Knowledge Base, on the other hand, reveals that wParam
- contains the PM_ flags that were used in the call to
- PeekMessage(), so your message hook can, for example, determine
- if the message was being removed or not with code like this:
-
- if(wParam & PM_REMOVE)^
- //... then message is being removed^
- else^
- //... message is not being removed^
-
- Note that your hook may want to ignore the message if it is not
- being removed, since your hook will get called again when the
- same message is removed by some future call to GetMessage() or
- PeekMessage().
-
- Submitted by V. Ramachandran.^
- Reference: Microsoft Knowledge Base article Q104068
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #72
- TYPE: Win3.1
- TOPIC: GetInstanceData (2.x)
- KEYWORD: GetInstanceData
-
- Both the documentation and windows.h declare the second
- parameter as a BYTE*. Unfortunately, that declaration is only
- correct if you are using a memory model with near data (small or
- medium memory models), and will be incorrect for large or huge
- memory models. The correct declaration for this argument is
- BYTE NEAR*.
-
- Submitted by Martin Cooper.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #73
- TYPE: Win3.1
- TOPIC: MENUITEMTEMPLATE (3.0)
- KEYWORD: MENUITEMTEMPLATE
-
- Missing from the list of bits you can turn on in mtOption is
- MF_END (0x0080), which indicates that the item terminates
- the menu.
-
- Submitted by V. Ramachandran.
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #74
- TYPE: Win3.1
- TOPIC: AddAtom (2.x)
- KEYWORD: AddAtom
-
- AddAtom() handles strings that begin with "#" specially:
- it expects the string following the "#" to be a string
- of digits, and returns an atom is value is the 16-bit
- binary representation of that string of digits. Unfortunately,
- if your first call to AddAtom() is with a string like "#nondigits",
- it will produce a divide by zero fault. Two workarounds
- are possible: either make sure your first call to AddAtom()
- does not contain such a string, or call InitAtomTable()
- before calling AddAtom() for the first time.
-
- Submitted by V. Ramachandran.^
- Reference: MSKB PSS ID Number: Q103036
-
-
- ------------------------------------------------------------
-
-
- WDJ SDK Annotation #75
- TYPE: Win3.1
- TOPIC: DCB (2.x)
- KEYWORD: DCB
-
- When setting the BaudRate field, do not use the constant
- CBR_14400; Windows 3.1's COMM.DRV has a bug that will produce
- communications problems due to a bad table entry for that
- constant. Instead, set BaudRate to the integer 14400 to
- communicate at 14400 baud.
-
- Submitted by Manfred Keul.^
- Reference: Microsoft Knowledge Base article Q83232.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #76
- TYPE: Win3.1
- TOPIC: RegisterRoutine WinHelp macro
- KEYWORD: RegisterRoutine WinHelp macro
-
- The documentation does not reveal how to specify the return type
- of the function. You do this by inserting a type-specifying
- character followed by an equal sign in the third parameter
- string. For example, to register FindWindow() (which takes
- two far strings and returns a 16-bit unsigned integer), you
- might use:
-
- RR("USER", "FindWindow", "u=SS");
-
- Note that if you do not specify a return type when you register
- a function, you cannot use that function in an IfThen or
- IfThenElse macro.
-
- Submitted by Sudhir Menon.
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #77
- TYPE: Win3.1
- TOPIC: RTF Tokens
- KEYWORD: RTF Tokens
-
- Strangely, the tokens "emc", "eml", and "emr" are
- misspelled in the online help -- they should be
- "ewc", "ewl", and "ewr", where the "ew" stands for
- Embedded Window. Note that this are not really RTF
- tokens, but literal text. The help compiler scans
- for any text you have entered of the form "{ewx commands}"
- in order to detect embedded window commands. Such text,
- when translated by your word processor into RTF, looks
- like this: "\{ewx commands\}".
-
- Submitted by John Sawyer.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #78
- TYPE: Win3.1
- TOPIC: WM_ENTERIDLE (2.x)
- KEYWORD: WM_ENTERIDLE
-
- Note that you can elect to suppress the WM_ENTERIDLE
- message for a particular modal dialog box by defining
- it with the DS_NOIDLEMSG window style bit.
-
- Submitted by V. Ramachandran.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #79
- TYPE: Win3.1
- TOPIC: WM_SYSCOMMAND (2.x)
- KEYWORD: WM_SYSCOMMAND
-
- You can use this message with SC_MENUKEY to simulate the
- user selecting a menu with an accelerator key. For example,
- to simulate the user accessing the "File" menu, you might
- use the following code:
-
- PostMessage(hWnd, WM_SYSCOMMAND, SC_MENUKEY, MAKELPARAM('f',0));
-
- Submitted by Jay Giganti.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #80
- TYPE: Win3.1
- TOPIC: wsprintf
- KEYWORD: wsprintf
-
- The documentation says the second parameter is an LPSTR,
- but it is actually an LPCSTR (and so declared in windows.h),
- so it's safe to use a string constant.
-
- Submitted by: V. Ramachandran.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #81
- TYPE: Win3.1
- TOPIC: _lread (2.x)
- KEYWORD: _lread
-
- If you call _lread() to read a floppy when there is no
- diskette in the drive, Windows puts up a system error
- message box ("Cannot Read from Drive...") with Retry and
- Cancel buttons. If the user presses the Cancel button,
- _lread() returns a non-negative number, indicating success.
- It should return HFILE_ERROR instead.
-
- To avoid this error, call SetErrorMode(SEM_NOOPENFILEERRORBOX)
- before calling _lread(), then it will correctly return -1 on
- failure.
-
- Submitted by: V. Ramachandran.^
- Reference: MSDN PSS ID No. Q111587.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #82
- TYPE: Win3.1
- TOPIC: WM_COMPAREITEM (3.0)
- KEYWORD: WM_COMPAREITEM
-
- The documentation for WM_COMPAREITEM says that the parent of
- owner-drawn listboxes with the LBS_SORT (or CBS_SORT) styles
- will get this message in order to determine the relative
- position. However, Windows will not send the WM_COMPAREITEM
- message if the LBS_HASSTRINGS style bit is set, even if it
- is an owner-drawn listbox with the LBS_SORT style. The same
- is true for comboboxes.
-
- Submitted by: V. Ramachandran.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #83
- TYPE: Win3.1
- TOPIC: DOCINFO (3.1)
- KEYWORD: DOCINFO
-
- The documentation fails to point out that lpszOutput is
- limited to 32 characters, including the null terminating
- byte. If you use a string longer than that, the trailing
- characters will be ignored. For example, if you use a
- string containing the too-long path:
-
- c:\usr\ts\issues\pending\12345678\abcdefgh.out
-
- the actual file that gets created will be:
-
- c:\usr\ts\issues\pending\123456
-
- Submitted by V. Ramachandran.
-
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #84
- TYPE: Win3.1
- TOPIC: SetAbortProc function
- KEYWORD: SetAbortProc
-
-
- SetAbortProc() returns a negative value, which is documented
- as indicating failure. However, the return value from
- SetAbortProc does not indicate success or failure of the
- function, so don't depend on the return value for anything.
-
- Submitted by: V. Ramachandran.^
- Reference: MSDN PSS ID No. Q109540.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #85
- TYPE: Win3.1
- TOPIC: BN_DISABLE (2.x)
- KEYWORD: BN_DISABLE
-
- The documentation claims the button sends this notification
- whenever it gets disabled. In fact, Windows 3.1 buttons do
- not appear to ever send this notification!
-
- Submitted by: V. Ramachandran.
-
-
-
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #86
- TYPE: Win3.1
- TOPIC: BN_DOUBLECLICKED (2.x)
- KEYWORD: BN_DOUBLECLICKED
-
- The documentation fails to point out that this notification
- is only sent for buttons that have the BS_OWNERDRAW or
- BS_RADIOBUTTON styles. No other types of buttons generate
- this notification
-
- Submitted by: V. Ramachandran.
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #87
- TYPE: Win3.1
- TOPIC: WM_DROPFILES (3.1)
- KEYWORD: WM_DROPFILES
-
- Documentation for the undocumented handle has since been
- published by Microsoft in Microsoft Systems Journal. This
- handle points to a structure like this:
-
- typedef struct {^
- int wSize; // Number of bytes in this structure^
- POINT ptMousePos; // Mouse position^
- BOOL fInNonClientArea;// TRUE if mouse was in client area^
- // Pathnames begin after structure each one zero-terminated^
- // Zero-length pathname used to indicate the end^
- } DROPFILESTRUCT, FAR *LPDROPFILESTRUCT;^
-
- The Win32 version of this structure is slightly different. The
- first field becomes a 4-byte rather than a 2-byte integer, and
- the structure contains an additional BOOL field at the end that
- is TRUE if the pathnames are in Unicode rather than ANSI
- strings.
-
- Submitted by V. Ramachandran.^
- Reference: May/June 1992 Microsoft Systems Journal^
- February 1994 Microsoft Systems Journal
-
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #87
- TYPE: Win32
- TOPIC: WM_DROPFILES
- KEYWORD: WM_DROPFILES AND Parameters
-
- Documentation for the undocumented handle has since been
- published by Microsoft in Microsoft Systems Journal. This
- handle points to a structure like this:
-
- typedef struct {^
- int wSize; // Number of bytes in this structure^
- POINT ptMousePos; // Mouse position^
- BOOL fInNonClientArea;// TRUE if mouse was in client area^
- // Pathnames begin after structure each one zero-terminated^
- // Zero-length pathname used to indicate the end^
- } DROPFILESTRUCT, FAR *LPDROPFILESTRUCT;^
-
- The Win32 version of this structure is slightly different. The
- first field becomes a 4-byte rather than a 2-byte integer, and
- the structure contains an additional BOOL field at the end that
- is TRUE if the pathnames are in Unicode rather than ANSI
- strings.
-
- Submitted by V. Ramachandran.^
- Reference: May/June 1992 Microsoft Systems Journal^
- February 1994 Microsoft Systems Journal
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #88
- TYPE: Win3.1
- TOPIC: List box messages
- KEYWORD: List box messages
-
- Internally, listboxes maintain two 32-bit DWORDs for each
- listbox item. The first DWORD points to the text for the item
- and the second DWORD contains whatever custom data you would
- like; you can get it via LB_GETITEMDATA or set it via
- LB_SETITEMDATA. Some messages refer to one or the other of
- these DWORDs, depending on whether the LBS_HASSTRINGS style is
- set:
-
- Message LBS_HASSTRINGS? Refers to:^
- ==========================================================^
- LB_ADDSTRING Yes text pointer (lParam)^
- LB_ADDSTRING No custom data (lParam)^
- LB_INSERTSTRING Yes text pointer (lParam)^
- LB_INSERTSTRING No custom data (lParam)^
- LB_GETTEXT Yes returns text pointer^
- LB_GETTEXT No returns custom data^
- LB_GETITEMDATA either returns custom data^
- LB_SETITEMDATA either sets custom data (lParam)^
- WM_DRAWITEM either custom data (in itemData field)^
-
- In other words, if LBS_HASSTRINGS is not set, you cannot access
- the normal text pointer -- all messages operate on the custom
- data. But if LBS_HASSTRINGS is set, you can access both the
- normal text as well as the extra DWORD of custom data.
-
- Submitted by V. Ramachandran
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #89
- TYPE: Win3.1
- TOPIC: SetTimer (2.x)
- KEYWORD: SetTimer
-
- Though the documentation does not mention this, you can
- change the timer interval after you create the timer. If
- you call SetTimer() with a window handle and a timer ID
- equal to an existing timer and specify a different time
- interval, SetTimer() updates the timer to the new time
- interval.
-
- Example:
-
- Use the following line to set a timer to a particular time
- interval.
-
- UINT nTimerID = SetTimer (hWnd, TIMER_ID, TIME_INTERVAL, NULL)
-
- Calling the following line will reset the timer to twice the
- time interval.
-
- nTimerID = SetTimer (hWnd, TIMER_ID, 2*TIME_INTERVAL, NULL)
-
- Submitted by V. Ramachandran.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #90
- TYPE: Win3.1
- TOPIC: TranslateAccelerator (2.x)
- KEYWORD: TranslateAccelerator
-
- Contrary to the documentation, both WM_INITMENU and
- WM_INITMENUPOPUP get sent, even if the menu item is disabled,
- and even if the window is minimized and the keystroke matches no
- menu items.
-
- Submitted by V. Ramachandran.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #91
- TYPE: Win3.1
- TOPIC: GetPrivateProfileInt (3.0)
- KEYWORD: GetPrivateProfileInt
-
- The documentation says you must use a positive integer
- in the range 0 through 32,767 (0x7FFF) for the third
- argument, which is the default value the function returns
- if it cannot locate the desired entry in the .ini file.
- In fact, you can pass any legal integer value for this
- parameter -- it's just that since the function's return
- type is defined to be UINT, you must cast the result to
- int if you want to treat the result as a negative number.
- For example, the following code works correctly, despite
- what the documentation says:
-
- int Val = (int)GetPrivateProfileInt(
- "MyLib", "Debug", -1, "MyLib.ini");
- if(Val == -1)
- /* then no such entry found */
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #92
- TYPE: Win32
- TOPIC: WM_NOTIFY
- KEYWORD: WM_NOTIFY AND "See also"
-
- If your dialog procedure handles a WM_NOTIFY that requires a
- return value, note that you MUST both return a non-zero
- value (to indicate to the dialog manager that you wish to
- specify a return value for the message) AND store the
- desired return value for the message in the window field
- DWL_MSGRESULT. The standard Windows header file windowsx.h
- provides a macro called SetDlgMsgResult() that makes this
- easy:
-
- #include <windowsx.h>
- //...
- case WM_NOTIFY :
- {
- NMHDR* Head = (NMHDR*)lParam;
- if(Head->code == LVN_ENDLABELEDIT)
- // allow user to edit listview labels
- return SetDlgMsgResult(Dialog, WM_NOTIFY, TRUE);
- }
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #92
- TYPE: Win32
- TOPIC: LVN_ENDLABELEDIT
- KEYWORD: LVN_ENDLABELEDIT AND Parameters
-
- If your dialog procedure handles a WM_NOTIFY that requires a
- return value (as this one does), note that you MUST both
- return a non-zero value (to indicate to the dialog manager
- that you wish to specify a return value for the message) AND
- store the desired return value for the message in the window
- field DWL_MSGRESULT. The standard Windows header file
- windowsx.h provides a macro called SetDlgMsgResult() that
- makes this easy:
-
- #include <windowsx.h>
- //...
- case WM_NOTIFY :
- {
- NMHDR* Head = (NMHDR*)lParam;
- if(Head->code == LVN_ENDLABELEDIT)
- // allow user to edit listview labels
- return SetDlgMsgResult(Dialog, WM_NOTIFY, TRUE);
- }
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #92
- TYPE: Win32
- TOPIC: LVN_BEGINLABELEDIT
- KEYWORD: LVN_BEGINLABELEDIT AND Parameters
-
- If your dialog procedure handles a WM_NOTIFY that requires a
- return value (as this one does), note that you MUST both
- return a non-zero value (to indicate to the dialog manager
- that you wish to specify a return value for the message) AND
- store the desired return value for the message in the window
- field DWL_MSGRESULT. The standard Windows header file
- windowsx.h provides a macro called SetDlgMsgResult() that
- makes this easy:
-
- #include <windowsx.h>
- //...
- case WM_NOTIFY :
- {
- NMHDR* Head = (NMHDR*)lParam;
- if(Head->code == LVN_BEGINLABELEDIT)
- // allow user to edit listview labels
- return SetDlgMsgResult(Dialog, WM_NOTIFY, FALSE);
- }
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #93
- TYPE: Win3.1
- TOPIC: GetWindowText
- KEYWORD: GetWindowText
-
- GetWindowText() and GetDlgItemText() will not work when
- applied to a standard edit control that belongs to another
- application. The problem is that GetWindowText() and
- GetDlgItemText() attempt to optimize by directly examining
- the window caption of the target window. An edit control
- stores an empty string in its caption, not the edit control
- text, so this fails. You can avoid this bug by sending a
- WM_GETTEXT explicitly:
-
- HWND OtherEdit;
- char Buffer[256];
- SendMessage(OtherEdit, WM_GETTEXT,
- sizeof(Buffer), (LPARAM)Buffer);
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #93
- TYPE: Win3.1
- TOPIC: GetDlgItemText
- KEYWORD: GetDlgItemText
-
- GetWindowText() and GetDlgItemText() will not work when
- applied to a standard edit control that belongs to another
- application. The problem is that GetWindowText() and
- GetDlgItemText() attempt to optimize by directly examining
- the window caption of the target window. An edit control
- stores an empty string in its caption, not the edit control
- text, so this fails. You can avoid this bug by sending a
- WM_GETTEXT explicitly:
-
- HWND OtherEdit;
- char Buffer[256];
- SendMessage(OtherEdit, WM_GETTEXT,
- sizeof(Buffer), (LPARAM)Buffer);
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #94
- TYPE: Win32
- TOPIC: LVM_GETCOLUMNWIDTH
- KEYWORD: LVM_GETCOLUMNWIDTH AND Parameters
-
- The documentation claims that this message returns the
- column width if successful, "or zero otherwise". In fact,
- if you specify an invalid column number, this function
- returns garbage. Therefore, you cannot use this message to
- count the number of columns in a listview control. The
- associated message, LVM_GETCOLUMN, does correctly return
- zero when passed an invalid column number, so you can use
- LVM_GETCOLUMN to determine the number of columns in a
- listview control.
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #95
- TYPE: Win3.1
- TOPIC: SystemParametersInfo (3.1)
- KEYWORD: SystemParametersInfo
-
- The documentation says that the screen saver time out
- (SPI_GETSCREENSAVETIMEOUT) is specified in milliseconds. In
- fact, the value returned is in seconds.
-
- Submitted by: Carlton Guc
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #96
- TYPE: Win32
- TOPIC: LVN_ENDLABELEDIT
- KEYWORD: LVN_ENDLABELEDIT AND Parameters
-
- The documentation claims that there is no return value for
- this message. In fact, you should return FALSE if you want
- to reject the user's editing, or TRUE if you want to allow
- the changes to the listview item. If you are handling this
- notification inside a dialog procedure, remember that you
- must return a non-zero result AND store the message result
- (either TRUE or FALSE) in DWL_MSGRESULT, using either
- SetWindowLong() or the SetDlgMsgResult() macro (defined in
- windowsx.h).
-
- Submitted by: Poul A. Costinsky
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #98
- TYPE: Win32
- TOPIC: RegSetValueEx
- KEYWORD: RegSetValueEx AND "See also"
-
- For string-based data types, such as REG_SZ, this function
- behaves differently under Win95 and NT. Under Win95, if you
- pass a value of "abcd" and a length of 4, the function will
- actually append a null byte, and if you retrieve the value
- later, you will find it has a length of 5. Under NT, this
- function stores exactly what you tell it to store.
-
- Submitted by Paula Tomlinson.
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #97
- TYPE: Win32
- TOPIC: LVN_ITEMCHANGING
- KEYWORD: LVN_ITEMCHANGING AND Parameters
-
- The documentation incorrectly claims that you have to return
- TRUE to allow the change, or FALSE to prevent it. In fact,
- you have to return FALSE to allow the change or TRUE to
- prevent it.
-
- Submitted by V. Ramachandran.
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #99
- TYPE: Win32
- TOPIC: LV_DISPINFO
- KEYWORD: LV_DISPINFO AND Parameters
-
- The documentation says you can set the LVIF_DI_SETITEM flag
- in the mask member to have Windows store the string and not
- ask for it again. It fails to point out that this only
- works for subitem 0 (the first column), so you would still
- have to handle requests for the text of the other columns.
-
- Submitted by V. Ramachandran.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #100
- TYPE: Win32
- TOPIC: LVM_EDITLABEL
- KEYWORD: LVM_EDITLABEL AND Parameters
-
- Note that the listview control implements in-place editing
- by creating an edit control on the fly. Unfortunately, it
- assigns that edit control a child ID of IDOK, which means
- that the parent of the listview control will receive edit
- control notifications that it might not expect. For
- example, if your listview control is in a dialog box, and
- your dialog procedure contains code like this:
-
- // inside WM_COMMAND handler...
- if(ControlId == IDOK)
- EndDialog(Dialog, TRUE);
-
- Then it may terminate the dialog when the user starts
- editing a listview item (since the transient edit control
- will send notifications like EN_CHANGE, with a control ID of
- IDOK). The above code should read:
-
- // inside WM_COMMAND handler...
- if(ControlId == IDOK && NotifyCode == BN_CLICKED)
- EndDialog(Dialog, TRUE);
-
- to be safe.
-
-
-
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #101
- TYPE: Win3.1
- TOPIC: GetWindowTextLength (2.x)
- KEYWORD: GetWindowTextLength
-
- Due to a bug in Windows 3.1, both GetWindowTextLength() and
- WM_GETTEXTLENGTH return -1 if you use it on a combobox of
- style CBS_DROPDOWNLIST.
-
- Submitted by Mircea Neacsu
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #102
- TYPE: Win32
- TOPIC: LB_ADDSTRING
- KEYWORD: LB_ADDSTRING AND Parameters
-
- If you are planning to add a large number (more than 100) of
- strings by calling LB_ADDSTRING, LB_INSERTSTRING, LB_DIR, or
- LB_ADDFILE, consider first sending the new Win32 message
- LB_INITSTORAGE to give the listbox a chance to preallocate
- memory, thus speeding up the process.
-
- Submitted by V. Ramachandran.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #102
- TYPE: Win32
- TOPIC: LB_ADDSTRING
- KEYWORD: LB_ADDSTRING AND Parameters
-
- If you are planning to add a large number (more than 100) of
- strings by calling LB_ADDSTRING, LB_INSERTSTRING, LB_DIR, or
- LB_ADDFILE, consider first sending the new Win32 message
- LB_INITSTORAGE to give the listbox a chance to preallocate
- memory, thus speeding up the process.
-
- Submitted by V. Ramachandran.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #103
- TYPE: Win32
- TOPIC: LoadString
- KEYWORD: LoadString AND "See also"
-
- Even though resource strings are stored as Unicode for both
- Win95 and NT programs, Win95 does not provide an
- implementation of the Unicode version of LoadString()
- (LoadStringW()). This usually trips up NT programmers who
- want to create a single .exe for both operating systems and
- yet still use Unicode under NT. In that case, you must at
- runtime detect that you are running under Win95 and, in that
- case, explicitly call LoadStringA(). Otherwise, if you have
- compiled with _UNICODE defined, LoadString() will expand
- into LoadStringW(), which is just a stub that fails under
- Win95.
-
- Submitted by Paula Tomlinson.
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #104
- TYPE: Win32
- TOPIC: LVN_DELETEITEM
- KEYWORD: LVN_DELETEITEM AND Parameters
-
- The documentation implies that this notification
- arrives after the item is deleted. In fact, it
- arrives before the item is deleted from the listview
- control.
-
- Submitted by V. Ramachandran.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #105
- TYPE: Win32
- TOPIC: IsWindow
- KEYWORD: IsWindow AND Parameters
-
- The documentation claims this function returns TRUE if the
- given handle is a valid window handle. That was true under
- Windows 3.x and is true under Windows NT, but Windows 95
- returns a large non-zero value that is not equal to 1 (nor
- is it equal to the window handle). In an un-indexed help
- topic in the initial Win95 SDK, Microsoft reveals that
- Win95 functions with BOOL return types are only guaranteed
- to return non-zero when the documentation claims they
- return TRUE. Windows NT appears to behave as documented.
-
- Submitted by: David Lowndes
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #105
- TYPE: Win32
- TOPIC: GetClientRect
- KEYWORD: GetClientRect AND "See also"
-
- The documentation claims this function returns TRUE if the
- given handle is a valid window handle. That was true under
- Windows 3.x and is true under Windows NT, but Windows 95
- returns a large non-zero value that is not equal to 1 (nor
- is it equal to the window handle). In an un-indexed help
- topic in the initial Win95 SDK, Microsoft reveals that
- Win95 functions with BOOL return types are only guaranteed
- to return non-zero when the documentation claims they
- return TRUE. Windows NT appears to behave as documented.
-
- Submitted by: Ron Scott
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #106
- TYPE: Win32
- TOPIC: WM_GETDLGCODE
- KEYWORD: WM_GETDLGCODE AND Parameters
-
- The documentation WM_GETDLGCODE states that this message has
- no parameters. But the truth is that if the user presses a
- key, lParam will contain a pointer to a MSG structure
- containing information about the event that made Windows send
- the WM_GETDLGCODE message. This is indirectly documented in
- windowsx.h, where the HANDLE_WM_GETDLGCODE() macro passes
- two arguments to the handler: the window handle and (MSG
- FAR*)(lParam).
-
- Submitted by: Patrick Tennberg
- Reference: Microsoft Knowledge Base article Q83302
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #107
- TYPE: Win32
- TOPIC: DBT_DEVICEQUERYREMOVE
- KEYWORD: DBT_DEVICEQUERYREMOVE AND Parameters
-
- The documentation incorrectly says that you should return
- FALSE if you want to veto the device removal. In fact, you
- have to return BROADCAST_QUERY_DENY; returning FALSE will
- allow the device removal to proceed.
-
- Submitted by Paula Tomlinson.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #108
- TYPE: Win3.1
- TOPIC: LZOpenFile
- KEYWORD: LZOpenFile
-
-
- However, if lpszFile contains only a filename and extension
- (i.e. no path is specified), then LZOpenFile() use the same
- searching logic as OpenFile(). If no file with the matching
- name (and extension) is found, then it searches for the
- compressed filename. The compressed file has a _ as the
- last character (e.g., the compressed version of "readme.txt"
- is "readme.tx_"). Therefore if you use LZOpenFile() to open
- a file called "readme.txt", it searches as follows:
-
- 1) it looks for "readme.txt" using the same search
- algorithm as OpenFile().
- 2) if the file was not found, it uses the same
- algorithm to search for "readme.tx_".
-
- That means LZOpenFile() might open a "readme.tx_" file from
- a directory other than the one you expected. Even if you
- specify the complete filename (such as
- "c:\demo\readme.txt"), LZOpenFile() first searches for the
- specified file, and if the specified filename is not found,
- it searches for the compressed file in the same directory
- ("c:\demo\readme.tx_").
-
- Submitted by V. Ramachandran.
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #109
- TYPE: Win32
- TOPIC: SetCapture
- KEYWORD: SetCapture AND Parameters
-
- This help topic does not document the fact that when the
- mouse is captured, menu hotkeys (for example, Alt+F for
- accessing the File menu) and other keyboard accelerators do
- not work (ex: Alt+F4). This is because DefWindowProc()
- handles the WM_SYSCHAR and WM_SYSCOMMAND messages
- differently if the mouse has been captured (by any window).
-
- DefWindowProc() processes the WM_SYSCHAR message to check if
- the pressed key is a menu hotkey (Alt+F for example). If it
- is, then it causes the menu to drop down. However, if the
- mouse is captured, it does not do the above action.
- Whenever DefWindowProc() sees a WM_SYSCOMMAND and finds that
- the mouse is captured, then it does nothing.
-
- Submitted by V. Ramachandran.
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #110
- TYPE: Win32
- TOPIC: RegCreateKey
- KEYWORD: RegCreateKey AND "See also"
-
- The documentation for RegCreateKey(), RegCreateKeyEx(),
- RegOpenKey(), and RegOpenKeyEx() all list several predefined
- handles you can use, such as HKEY_CURRENT_USER. However,
- they fail to document the predefined key
- HKEY_CURRENT_CONFIG, which has a structure similar to the
- registry tree under HKEY_LOCAL_MACHINE, but is for storing
- information specific to the current hardware profile.
-
- Submitted by Paula Tomlinson.
-
-
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #111
- TYPE: Win32
- TOPIC: CreateFile
- KEYWORD: CreateFile AND "See also"
-
- The documentation claims CreateFile() returns a handle that
- can be used to access the object. However, under both NT
- and Win95, CreateFile() will appear to succeed and return a
- valid handle if you attempt to open a file with
- GENERIC_WRITE permissions on a read-only medium (e.g.,
- protected floppy or CD-ROM). If you then try to perform a
- write with the returned handle, that will fail.
-
-
- Submitted by: David Lowndes
-
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #112
- TYPE: Win32
- TOPIC: GetWindowText
- KEYWORD: GetWindowText AND "See Also"
-
- The third argument is the "maximum numbers of characters to
- copy". It may not be clear that this number must include
- the NULL byte so, for example, it never makes sense to set
- this argument to 1 since all you could get back is a NULL
- byte. If you want to use GetWindowText() to retrieve a
- single character (e.g., from an edit control), you would
- have to specify a length of 2 -- one for the character and
- one for the terminating NULL byte.
-
- Submitted by: Tony Yuricich
-
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #113
- TYPE: Win32
- TOPIC: keybd_event
- KEYWORD: keybd_event AND "See also"
-
- You can use this function to toggle keys such as the Caps
- Lock, Scroll Lock, and Num Lock. Unfortunately, though
- toggling these three keys works correctly under NT, you
- cannot use this function to toggle the Num Lock key under
- Win95.
-
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #114
- TYPE: Win3.1
- TOPIC: WM_CTLCOLOR (2.x)
- KEYWORD: WM_CTLCOLOR
-
-
-
- The documentation incorrectly states that "the return value
- from this message has no effect on a button with the
- BS_PUSHBUTTON or BS_DEFPUSHBUTTON style." In fact, returning
- a brush handle in response to this message appears to
- determine the color of the pushbutton window background,
- which is visible as the tiny areas in the corners of the
- pushbutton window. Note that under Windows 95, pushbuttons
- fill the entire client area of their windows, thus hiding
- the window background from view.
-
- Submitted by: Forest Wilkinson
-
-
-
-
- ------------------------------------------------------------
-
-
-
- WDJ SDK Annotation #115
- TYPE: Win32
- TOPIC: GlobalDeleteAtom
- KEYWORD: GlobalDeleteAtom AND "See also"
-
- The documentation for GlobalDeleteAtom states:
-
- "The only way to ensure that an atom has been deleted from the
- atom table is to call this function repeatedly until it fails."
-
- Unfortunately, a 32-bit program running under Win NT 3.51 never fails,
- making for an infinite loop (Windows 95 functions as documented).
- Microsoft says this may be fixed in the next release (NT 4.0).
-
- Submitted by Ken Brown
-
-
- ------------------------------------------------------------
-
- WDJ SDK Annotation #116
- TYPE: Win32
- TOPIC: LB_ADDSTRING
- KEYWORD: LB_ADDSTRING AND "See also"
-
- If your listbox has the WS_HSCROLL style, and if you are
- adding a string wider than the listbox, you may have to send
- a LB_SETHORIZONTALEXTENT message to make the horizontal
- scrollbar appear. The listbox does not automatically check
- each newly added string and add the horizontal scrollbar
- when a too-wide string is added or inserted.
-
-
-
-
- ------------------------------------------------------------
-
-
-
- WDJ SDK Annotation #117
- TYPE: Win32
- TOPIC: LB_DIR
- KEYWORD: LB_DIR AND "See also"
-
- If you pass a long filename to LB_DIR, it works
- under NT 3.51, but fails under Win95 because it
- relies on the 16-bit listbox which was not changed
- to handle long filenames. You can avoid the error
- by first translating the filename to a short filename
- by calling GetShortPathName(). The LB_DIR will not
- fail, but it will still display only the short versions
- of any long filenames in the subdirectory.
-
- Reference: Microsoft Knowledge Base article Q131286
-
-
-
-
- ------------------------------------------------------------
-
-
-
- WDJ SDK Annotation #118
- TYPE: Win32
- TOPIC: ReadFile
- KEYWORD: ReadFile AND "See also"
-
- The documentation correctly points out that Win95
- does not support OVERLAPPED I/O. However, it incorrectly
- states that you must pass a pointer to a structure of
- type OVERLAPPED if the file was created (or opened)
- with the flag FILE_FLAG_OVERLAPPED. In fact, if you
- pass a pointer (rather than NULL) under Windows 95,
- ReadFile() returns FALSE, and GetLastError() returns
- ERROR_INVALID_PARAMETER, whether or not the file
- was created/opened with the FILE_FLAG_OVERLAPPED
- flag. That means that if you want to code a call
- to ReadFile() that works correctly for both
- synchronous and asynchronous I/O, you must detect
- at runtime that you're running under Win95 and
- treat that case differently.
-
-
-
- -----------------------------------------------------------------------
-
-
- WDJ SDK Annotation #119
- TYPE: Win32
- TOPIC: WinMain
- KEYWORD: WinMain AND "See also"
-
- Note that the string passed in lpCmdLine is not the same as
- the string returned by GetCommandLine(). The string in
- lpCmdLine contains the command line arguments only, but
- GetCommandLine() returns the program name followed by the
- arguments.
-
- If you specify the following command: 'winword abc.doc', and
- winword exists in d:\msoffice\winword.exe, lpCmdLine will
- contain 'abc.doc', while GetCommandLine will return
- '"d:\msoffice\winword.exe" abc.doc' Note the double quotes
- around the exe name.
-
- Submitted by Phil Rodgers.
-
- ----------------------------------------------------------------------
-
-
- WDJ SDK Annotation #119
- TYPE: Win32
- TOPIC: GetCommandLine
- KEYWORD: GetCommandLine AND "See also"
-
- Note that the string passed in the lpCmdLine parameter to
- WinMain is not the same as the string returned by
- GetCommandLine(). GetCommandLine() returns the complete
- program name enclosed in double quotes, followed by the
- arguments; whereas the lpCmdLine parameter of WinMain
- contains the command line arguments only.
-
- If you specify the following command: 'winword abc.doc', and
- winword exists in d:\msoffice\winword.exe, lpCmdLine will
- contain 'abc.doc', while GetCommandLine will return
- '"d:\msoffice\winword.exe" abc.doc' Note the double quotes
- around the exe name.
-
- Submitted by Phil Rodgers.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #120
- TYPE: Win32
- TOPIC: ShellAbout
- KEYWORD: ShellAbout AND "See also"
-
- The documentation says that in Windows 95 ShellAbout will
- prepend "Microsoft Windows" to the title of the application.
- This is not true. Actually, this function prepends only
- "Microsoft", so if your app is called "MyApp", the title
- will read "Microsoft MyApp".
-
- Submitted by Luis A. Ramos.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #121
- TYPE: MFC 4
- TOPIC: CPropertySheet::SetTitle
- KEYWORD: SetTitle AND CPropertySheet
-
- The parameters to this function are interchanged: it should
- actually read:
-
- void SetTitle (LPCTSTR lpszText, UINT nStyle);
-
- Submitted by Margaret M. O'Connell.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #122
- TYPE: MFC 1.5x
- TOPIC: CCmdTarget::GetIDispatch
- KEYWORD: GetIDispatch AND CCmdTarget
-
- The MFC 1.5x documentation incorrectly states that this
- function takes no parameters. It should read:
-
- LPDISPATCH GetIDispatch (BOOL bAddRef)
- bAddRef - specifies whether to increment
- the reference count for the object.
-
- This has been corrected in the MFC 4.0 documentation.
-
- Submitted by V.Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #123
- TYPE: Win16
- TOPIC: LB_SELECTSTRING
- KEYWORD: LB_SELECTSTRING
-
- win31wh.hlp fails to mention that this message works only
- with single select listboxes. For multi-select listboxes it
- returns LB_ERR.
-
- Submitted by Dino Esposito.
-
- ----------------------------------------------------------------------
-
-
-
- WDJ SDK Annotation #124
- TYPE: Win32
- TOPIC: AdjustWindowRect
- KEYWORD: AdjustWindowRect AND "See also"
-
- The documentation for AdjustWindowRect() and
- AdjustWindowRectEx() has a number of problems.
-
- 1. Though the documentation says that window titles and
- borders are not taken into account, the function does
- account for these styles.
-
- 2. Add 1 to the rect.bottom returned by this function.
- There is a one-off error in the y direction.
-
- 3. The meaning of the rect parameter is not well explained.
- The input to AdjustWindowRectEx is the window coordinates of
- the top-left and bottom-right corners of the desired client
- area. AdjustWindowRectEx inflates the specified rectangle
- to include the caption, border and other non-client objects
- specified by the style parameter.
-
-
- Reference: MSDN Dr.GUI #10 - Calculated Client Window Size.
-
- Submitted by Etay Szekely.
-
- ----------------------------------------------------------------------
-
-
- WDJ SDK Annotation #124
- TYPE: Win32
- TOPIC: AdjustWindowRectEx
- KEYWORD: AdjustWindowRectEx AND "See also"
-
- The documentation for AdjustWindowRect() and
- AdjustWindowRectEx() has a number of problems.
-
- 1. Though the documentation says that window titles and
- borders are not taken into account, they function does
- account for these styles.
-
- 2. Add 1 to the rect.bottom returned by this function.
- There is a one-off error in the y direction.
-
- 3. The meaning of the rect parameter is not well explained.
- The input to AdjustWindowRectEx is the window coordinates of
- the top-left and bottom-right corners of the desired client
- area. AdjustWindowRectEx inflates the specified rectangle
- to include the caption, border and other non-client objects
- specified by the style parameter.
-
-
- Reference: MSDN Dr.GUI #10 - Calculated Client Window Size.
-
- Submitted by Etay Szekely.
-
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #125
- TYPE: MFC 3.1 and 3.2
- TOPIC: CImageList::DeleteObject
- KEYWORD: DeleteObject AND "See also" NOT HRESULT
-
- VC++ 2.1 and 2.2 help files incorrectly documented this
- function to delete image lists, while it actually never
- existed. The correct function to delete an image list is
- CImageList::DeleteImageList(); it returns non-zero if
- successful and zero if it fails.
-
- This error is corrected in the VC++ 4.0 documentation.
-
- Submitted by Barry Tannenbaum.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #126
- TYPE: Win32
- TOPIC: AVIFileOpen
- KEYWORD: AVIFileOpen AND "See also"
-
- The documentation specifies that using the OF_CREATE flag
- will cause an existing file to be truncated to zero length.
- In reality, it has no effect: the file length remains the
- same, and the old data is intact once the file is closed.
-
- Submitted by Tim Lesher.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #127
- TYPE: Win16
- TOPIC: CBTProc
- KEYWORD: CBTProc
-
- The CBTProc documentation fails to mention that you can
- return 0 to allow the operation and 1 to prevent it for
- HCBT_SETFOCUS notification also. The documentation has been
- corrected in the Win32 help file.
-
- Submitted by V.Ramachandran.
-
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #128
- TYPE: Win32
- TOPIC: GetDialogBaseUnits
- KEYWORD: GetDialogBaseUnits AND "See also"
-
- GetDialogBaseUnits() does not return correct dialog base
- units if the dialog is not using the system font. Use the
- following function instead:
-
- DWORD WDJ_GetDialogBaseUnits (HWND Dialog)
- {
- int BaseX, BaseY;
- RECT R;
- SetRect (&R, 0, 0, 4, 8);
- MapDialogRect (Dialog, &R);
- BaseX = R.right;
- BaseY = R.bottom;
- return (DWORD)MAKELONG (BaseX, BaseY);
- }
-
- Reference: p54, January 1996 Windows Developer's Journal.
-
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #129
- TYPE: Win32
- TOPIC: GetShortPathName
- KEYWORD: GetShortPathName AND "See also"
-
- The documentation fails to mention that this function returns an error
- if the specified long path (first parameter) is invalid.
-
- Submitted by Ken Brown.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #130
- TYPE: MFC
- TOPIC: CCheckListBox::Create
- KEYWORD: CCheckListBox::Create AND "See also"
-
- The documentation mentions that the dwStyle parameter could be any
- of the specified listbox styles. However, the dwStyle parameter should
- NOT be LBS_MULTICOLUMN or LBS_USETABSTOPS. Morever, you need to specify
- LBS_OWNERDRAWFIXED and LBS_HASSTRINGS. You can specify
- LBS_OWNERDRAWVARIABLE instead of LBS_OWNERDRAWFIXED, but then you need to
- override CCheckListBox::DrawItem, otherwise the debug version will ASSERT.
-
- Submitted by Sudhir Menon.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #131
- TYPE: Win32
- TOPIC: TBBUTTON
- KEYWORD: TBBUTTON AND "See also"
-
- The structure is actually defined as follows in commctrl.h. Under Win32
- 2 extra padding bytes are added.
-
- typedef struct _TBBUTTON {
- int iBitmap;
- int idCommand;
- BYTE fsState;
- BYTE fsStyle;
- #ifdef _WIN32
- BYTE bReserved[2];
- #endif
- DWORD dwData;
- int iString;
- } TBBUTTON, NEAR* PTBBUTTON, FAR* LPTBBUTTON;
- typedef const TBBUTTON FAR* LPCTBBUTTON;
-
- Submitted by Eric Heimburg.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #132
- TYPE: Win32
- TOPIC: EM_POSFROMCHAR
- KEYWORD: EM_POSFROMCHAR AND "See also"
-
- The documentation for the wParam, lParam and return value is
- completely wrong. It should be as follows:
-
- wParam - address of point structure to retrieve the coordinates
- lParam - zero based index of character
- Return value - not used
-
- Reference: PSS Q137805
-
- Submitted by Fred Heidrich.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #133
- TYPE: Win32
- TOPIC: EM_CHARFROMPOS
- KEYWORD: EM_CHARFROMPOS AND "See also"
-
- The documentation for the lParam and return value is wrong. It
- should be as follows:
-
- wParam - 0 (not used)
- lParam - Specifies a pointer to a POINT structure that contains the
- coordinates for the character position wanted.
- Return value - specifies the character index
-
- Reference: PSS Q137805
-
- Submitted by Fred Heidrich.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #134
- TYPE: MFC 4.0
- TOPIC: CEdit::PosFromChar
- KEYWORD: CEdit::PosFromChar AND "See also"
-
- The MFC wrapper internally calls the EM_POSFROMCHAR function passing
- the documented values. Unfortunately, there is a documentation error in
- EM_POSFROMCHAR, and therefore PosFromChar will not work correctly.
-
- Read SDK Annotation #132 or PSS Q137805 for more details.
- This error has been corrected in MFC 4.1
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #135
- TYPE: MFC 4.0
- TOPIC: CEdit::CharFromPos
- KEYWORD: CEdit::CharFromPos AND "See also"
-
- The MFC wrapper internally calls the EM_CHARFROMPOS function passing
- the documented values. Unfortunately, there is a documentation error in
- EM_CHARFROMPOS, and therefore CharFromPos will not work correctly.
-
- Read SDK Annotation #133 or PSS Q137805 for more details.
- This error has been corrected in MFC 4.1
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #136
- TYPE: Win32
- TOPIC: BM_SETIMAGE
- KEYWORD: BM_SETIMAGE AND "See also"
-
- The documentation for wParam is incorrect. wParam actually specifies the
- type of handle passed in lParam. It must be set either IMAGE_BITMAP or
- IMAGE_ICON.
-
- Also, this message will work only on buttons created with the
- BS_BITMAP or BS_ICON style.
-
- Reference: PSS Q125673
-
- Submitted by Paula Tomlinson.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #137
- TYPE: Win16
- TOPIC: GetOpenFileName
- KEYWORD: GetOpenFileName
-
- In 16-bit Windows, if you call GetOpenFileName with a string buffer of 10
- and set nMaxFile to 10, and the user selected a file whose full path name
- is 10 characters long, Windows appends a NULL character at the 11th byte
- and returns the filename. This behaviour remains in Win95.
-
- Therefore, if you set nMaxFile to n, specify a buffer of length n+1 before
- calling this function.
-
- Reference: March TechNet CD Q137194
-
- Submitted by: V.Ramachandran.
-
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #137
- TYPE: Win32
- TOPIC: GetOpenFileName
- KEYWORD: GetOpenFileName AND "See also"
-
- In 16-bit Windows, if you call GetOpenFileName with a string buffer of 10
- and set nMaxFile to 10, and the user selected a file whose full path name
- is 10 characters long, Windows appends a NULL character at the 11th byte
- and returns the filename. This behaviour remains in Win95.
-
- Therefore, if you set nMaxFile to n, specify a buffer of length n+1 before
- calling this function.
-
- Reference: March TechNet CD Q137194
-
- Submitted by: V.Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #138
- TYPE: Win32
- TOPIC: LB_DIR
- KEYWORD: LB_DIR AND "See also"
-
- Sending a LB_DIR message to a listbox that specifies a long filename in
- the lParam returns LB_ERR in Windows 95, but works fine under Windows
- NT 3.51
-
- In order to work around this bug, call GetShortPathName on the long
- filename and pass the short filename to LB_DIR.
-
- Reference: March TechNet CD Q131286
-
- Submitted by: V.Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #139
- TYPE: Win16
- TOPIC: EM_SETSEL
- KEYWORD: EM_SETSEL
-
- The SDK documentation mentions that if wParam is 0, the caret is scrolled
- into view, and if wParam is 1 it is not scrolled into view. However,
- this parameter is not used for single line edit controls.
-
- Also, the order of the start and end positions specified in the lParam
- is not respected by single line edit controls.
-
- Both wParam and lParam work as documented for multiline edit controls.
-
- Reference: MSDN PSS Q102641, Q64758.
-
- Submitted by: V.Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #140
- TYPE: Win32
- TOPIC: STGM
- KEYWORD: STGM AND "See also"
-
- The documentation fails to mention that for all storage and stream
- creation functions, you HAVE to specify a share mode flag. For example,
- a call to StgCreateDocfile with STGM_CREATE | STGM_READWRITE will fail;
- while passing STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_READWRITE will
- work correctly.
-
- Submitted by: V.Ramachandran.
-
-
-
- -------------------------------------------------------------------------
-
- WDJ SDK Annotation #141
- TYPE: Win32
- TOPIC: WM_SETICON
- KEYWORD: WM_SETICON AND "See also"
-
- Contrary to what the documentation says, Windows uses the small icon in
- the window caption (including the caption of the minimized window).
- Windows uses the large icon when you press Alt+Tab to switch to another
- application.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #142
- TYPE: Win16
- TOPIC: JournalRecordProc
- KEYWORD: JournalRecordProc
-
- lParam is incorrectly documented -- it actually points to a
- EVENTMSG structure.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #143
- TYPE: Win32
- TOPIC: GetDeviceCaps
- KEYWORD: GetDeviceCaps AND "See also"
-
- The documentation fails to mention 2 additional values for the
- index parameter:
-
- SCALINGFACTORX - Scaling factor for the x-axis of a printer
- SCALINGFACTORY - Scaling factor for the y-axis of a printer
-
- Also, GetDeviceCaps provides the following 6 indices in place of
- printer Escapes:
-
- Index for GetDeviceCaps Printer Escape Replaced
- --------------------------------------------------------
- PHYSICALWIDTH GETPHYSPAGESIZE
- PHYSICALHEIGHT GETPHYSPAGESIZE
- PHYSICALOFFSETX GETPRINTINGOFFSET
- PHYSICALOFFSETY GETPRINTINGOFFSET
- SCALINGFACTORX GETSCALINGFACTOR
- SCALINGFACTORY GETSCALINGFACTOR
-
- Reference: MSDN Knowledge Base PSS Q125692
-
- Submitted by Sudhir Menon.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #144
- TYPE: Win32
- TOPIC: MessageBoxIndirect
- KEYWORD: MessageBoxIndirect AND "See also"
-
- The documentation incorrectly mentions that this function returns a
- BOOL value, and gives no description of it. In fact, the return value
- is an int, and it has the same meaning as the return value for MessageBox.
-
- Submitted by Phil Rodgers.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #145
- TYPE: Win32
- TOPIC: LVM_EDITLABEL
- KEYWORD: LVM_EDITLABEL AND "See also"
-
- Note that the listview control allows label editing
- by creating a child edit control with an ID of IDOK.
- That edit control will send notifications to the parent
- of the listview control (e.g., your dialog box), so
- if you have an "OK" button with the same ID, do not
- write code like this:
-
- if(Command == IDOK)
- EndDialog(Dialog, TRUE);
-
- since the first time the user edits a label, the dialog
- will immediately disappear as though the user pressed
- the "OK" button. Instead, use code like this:
-
- if(Command == IDOK && Code == BN_CLICKED)
- EndDialog(Dialog, TRUE);
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #146
- TYPE: Win32
- TOPIC: TVN_ENDLABELEDIT
- KEYWORD: TVN_ENDLABELEDIT AND "See also"
-
- When editing labels in a TreeView control which is part of a dialog,
- this notification is sent only if the user ends label editing using
- the mouse (by clicking outside the edit control). Using the Enter and
- Return keys do not work because the edit control does not handle the
- WM_GETDLGCODE correctly, and therefore IsDialogMessage processes these
- keys.
-
- In order to make the TreeView control accept the changes when the user
- presses Enter, and reject the changes on Escape, do the following:
-
- 1. In the TVN_BEGINLABELEDIT notification, get the edit contol handle
- using TVM_GETEDITCONTROL. Subclass the edit control.
-
- 2. In the subclassed procedure, handle the WM_GETDLGCODE message and
- return WM_WANTALLKEYS.
-
- 3. Handle the WM_CHAR message. When wParam is VK_ESCAPE, send a
- TVM_ENDLABELEDITNOW message to the edit control with fCancel = TRUE.
- When wParam is VK_RETURN, send TVM_ENDLABELEDITNOW with
- fCancel = FALSE. All other WM_CHAR messages should be passed to the
- default edit control procedure.
-
- 4. In the TVN_ENDLABELEDIT notification, remove the subclassing.
-
- Reference: MSDN article PSS Q130691
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #147
- TYPE: Win16
- TOPIC: GetWindowTextLength
- KEYWORD: GetWindowTextLength
-
- In Windows 3.1, calling GetWindowTextLength on a drop list
- combo box (CBS_DROPDOWNLIST) incorrectly returns -1.
-
- However in Win32 (for both 16 and 32 bit applications),
- GetWindowTextLength returns the length of the string in the static
- portion of the combo box.
-
- Submitted by Sinisa Djurekovic.
-
- ----------------------------------------------------------------------
-
-
- WDJ SDK Annotation #147
- TYPE: Win32
- TOPIC: GetWindowTextLength
- KEYWORD: GetWindowTextLength AND "See also"
-
- In Windows 3.1, calling GetWindowTextLength on a drop list
- combo box (CBS_DROPDOWNLIST) incorrectly returns -1.
-
- However in Win32 (for both 16 and 32 bit applications),
- GetWindowTextLength returns the length of the string in the static
- portion of the combo box.
-
- Submitted by Sinisa Djurekovic.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #147
- TYPE: MFC 1.x, 2.x
- TOPIC: CWnd::GetWindowText
- KEYWORD: CWnd::GetWindowText AND CString AND Parameters
-
- If you call GetWindowText (CString&) on a CWnd object which specifies a
- Combo box with the CBS_DROPDOWNLIST style, you will get an assertion
- in strcore.cpp.
-
- This is because GetWindowText internally calls GetWindowTextLength.
- Calling GetWindowTextLength on a drop list combo box (CBS_DROPDOWNLIST)
- incorrectly returns -1, and MFC asserts because -1 is an invalid length
- for a CString object.
-
- Submitted by Sinisa Djurekovic.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #148
- TYPE: Win32
- TOPIC: FindFirstFile
- KEYWORD: FindFirstFile AND "See also"
-
- In Windows 95, the FindFirstFile() function interprets a wildcard (?) as
- "any character" instead of "zero or one character," as you would expect.
- For example, if the files, TEMP.TXT and TEMPTEMP.TXT, are in the same
- directory, using FindFirstFile ("TEM?????.???", &findData) finds the
- TEMPTEMP.TXT file, but not the TEMP.TXT file:
-
- This function works correctly under Windows NT.
-
- Reference: MSDN PSS ID No. Q130860
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #149
- TYPE: Win32
- TOPIC: CreateDirectoryEx
- KEYWORD: CreateDirectoryEx AND "See also"
-
- When you specify a template directory string with two back slashes (\\)
- at the end of the string, CreateDirectoryEx returns FALSE indicating
- error, even though the API successfully created the new directory.
- GetLastError returns ERROR_INVALID_PARAMETER (87L).
-
- Under Windows 95, passing "c:\\" as the template directory (first
- parameter) to CreateDirectoryEx will return FALSE, even if it
- successfully created the new directory.
-
- The function works correctly under Windows NT.
-
- Reference: MSDN PSS ID No. Q140455
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #150
- TYPE: MFC
- TOPIC: CStatusBar::SetPaneText
- KEYWORD: CStatusBar::SetPaneText AND "See also"
-
- Just calling CStatusBar::SetPaneText will not display the text in the
- status bar pane. You need to add a UI update handler for the pane for the
- text to appear correctly.
-
- In order to set the text for pane index 4, and id ID_PANE_FOUR do:
- SetPaneText (4, "Some text", TRUE);
- and a UI handler in the message map as follows:
- ON_UPDATE_COMMAND_UI (ID_PANE_FOUR, OnUpdatePane)
- and in the appropriate .cpp file add:
- void CMyClass::OnUpdatePane (CCmdUI *pCmdUI)
- {
- pCmdUI->Enable ();
- }
-
- Reference: MSDN PSS No. Q109039
-
-
- ----------------------------------------------------------------------
-
-
- WDJ MFC Annotation #151
- TYPE: MFC 2.x
- TOPIC: CRecordSet::Open
- KEYWORD: CRecordSet::Open
-
- The documentation says that, for the param dwOptions, an enum
- "CRecordset::defaultOptions" can be specified, which will make the
- recordset updatable. However, this enum is not defined. Use
- "CRecordset::none" instead.
-
- Submitted by Nagendra R.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #152
- TYPE: Win16
- TOPIC: EnumFontFamProc
- KEYWORD: EnumFontFamProc
-
- The SDK documentation incorrectly mentions that the first parameter
- lpnlf points to a NEWLOGFONT structure, which is not defined at all.
- lpnlf actually points to a ENUMLOGFONT structure.
-
- Reference: MSDN KB Q87975
-
- Submitted by V.Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #153
- TYPE: Win32
- TOPIC: WM_CANCELMODE
- KEYWORD: WM_CANCELMODE AND "See also"
-
- The WM_CANCELMODE gets sent to the active window before another dialog or
- message box is displayed. It is not sent to the focus window as the
- documentation claims.
-
- Therefore if a OK Button in Dialog 1 displays Dialog 2, Dialog 1 gets a
- WM_CANCELMODE message and not the OK button, which should have been the
- case as per the documentation.
-
- Submitted by V.Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #154
- TYPE: Win32
- TOPIC: CreateWindow
- KEYWORD: CreateWindow AND "See also"
-
- The documentation does not mention that static controls created with the
- SS_SIMPLE style do not gray their text when they are disabled unlike
- static controls without the SS_SIMPLE style.
-
- Submitted by Nagendra R.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #155
- TYPE: MFC 4.x
- TOPIC: CFileDialog::GetNextPathName
- KEYWORD: CFileDialog::GetNextPathName
-
- If you select multiple files in a root drive, GetNextPathName returns
- strings with two back slashes '\' after the drive letter. For example, if
- you select the autoexec.bat and config.sys files from C:\ using a multiple
- selection file open dialog, GetNextPathName will return the strings:
- "c:\\autoexec.bat" and "c:\\config.sys". This problem does not appear when
- you select only one file.
-
- A workaround would be to check the strings returned by GetNextPathName for
- double back slashes, and remove them yourself.
-
- CString sFile = dlg.GetNextPathName (pos);
- #if _MFC_VER >= 0x0400
- if ((sFile [1] == ':') && (sFile [2] == '\\') && (sFile [3] == '\\')) {
- sFile = sFile.Left (3) + sFile.Right (sFile.GetLength () - 4);
- }
- #endif // end of MFC 4.x hack!
-
- Submitted by David Lowndes.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #156
- TYPE: MFC 4.x
- TOPIC: CToolTipCtrl::GetToolInfo
- KEYWORD: CToolTipCtrl::GetToolInfo
-
- The documentation incorrectly states that the first parameter should be
- of type LPTOOLINFO. The function actually accepts a CToolInfo& (reference
- to a undocumented CToolInfo class). If the call succeeds, the szText
- parameter of the CToolInfo variable contains the tooltip text.
-
- Submitted by Paul Stemper.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #157
- TYPE: MFC 4.x
- TOPIC: CToolTipCtrl::AddTool
- KEYWORD: CToolTipCtrl::AddTool
-
- The documentation fails to mention that you cannot set a tooltip to a
- static control using the AddTool function.
-
- Submitted by Sudhir Menon.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #158
- TYPE: MFC 4.x
- TOPIC: CTreeCtrl::GetNextVisibleItem
- KEYWORD: CTreeCtrl::GetNextVisibleItem
-
- GetNextVisibleItem and GetPrevVisibleItem return the next
- or previous item, not the next or previous visible item.
-
- Submitted by Mark Gorokhov.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #158
- TYPE: MFC 4.x
- TOPIC: CTreeCtrl::GetPrevVisibleItem
- KEYWORD: CTreeCtrl::GetPrevVisibleItem
-
- GetNextVisibleItem and GetPrevVisibleItem return the next
- or previous item, not the next or previous visible item.
-
- Submitted by Mark Gorokhov.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #159
- TYPE: MFC 4.x
- TOPIC: CFontDialog::GetCurrentFont
- KEYWORD: CFontDialog::GetCurrentFont
-
- Though the documentation mentions that you can call this function after
- calling DoModal, the function incorrectly ASSERTS that its window handle
- is not NULL.
-
- Instead, use the public CFontDialog member variable m_lf.
-
- Submitted by Tim Lesher.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #160
- TYPE: Win32
- TOPIC: WM_MOVE
- KEYWORD: WM_MOVE AND "See also"
-
- The SDK documentation tells you to use the following two lines to calculate
- the x, and y positions of the window after it has been moved.
-
- xPos = (int) LOWORD(lParam); // horizontal position
- yPos = (int) HIWORD(lParam); // vertical position
-
- Though this worked fine in 16-bit Windows, it will fail for negative
- coordinates in 32-bit Windows. Instead use the following two lines to
- calculate the coordinates:
-
- xPos = (int) (short)LOWORD(lParam); // horizontal position
- yPos = (int)(short) HIWORD(lParam); // vertical position
-
- Submitted by Steven M. Kinney.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #161
- TYPE: MFC 4.x
- TOPIC: CWnd::OnMove
- KEYWORD: CWnd::OnMove AND Parameters NOT LPRECT
-
- MFC supplies LOWORD (lParam) and HIWORD (lParam) of the WM_MOVE message
- for the x, and y parameters of this function, respectively. Since x and y
- are defined as integers, you will get very large numbers for negative
- coordinates.
-
- Whenever you want to handle the WM_MOVE message, do the following:
- 1. Define a message handler: ON_MESSAGE (WM_MOVE, OnMyMove) in the message
- map.
- 2. Write the OnMyMove function as follows:
- LRESULT ClassName::OnMyMove (WPARAM, LPARAM lParam)
- {
- x = (int) (short)LOWORD(lParam); // horizontal position
- y = (int)(short) HIWORD(lParam); // vertical position
-
- // Do your processing here ...
-
- return Default ();
- }
-
- Submitted by Steven M. Kinney.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #162
- TYPE: MFC 2.x
- TOPIC: CRecordset::Delete
- KEYWORD: CRecordset::Delete AND Remarks NOT Symptoms
-
- This function is incorrectly documented as returning BOOL. It actually
- returns void.
-
- This documentation error has been corrected in MFC 4.x
-
- Submitted by Tushar Bhatia.
-
-
- ----------------------------------------------------------------------
-
-
- WDJ SDK Annotation #163
- TYPE: Win32
- TOPIC: EM_GETLINE
- KEYWORD: EM_GETLINE AND "See also"
-
- When using this message under Win32s (1.30a and above) with
- the RichEdit control, the parameters the message takes are:
-
- wParam = 0;
- lParam = &em32s;
-
- Where em32s is a structure defined as:
-
- struct EM32S {
- DWORD wParam;
- DWORD lParam;
- };
-
- The documented wParam and lParam values are stored in the
- EM32S structure.
-
- Submitted by Larry Widing.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #163
- TYPE: Win32
- TOPIC: EM_LINEINDEX
- KEYWORD: EM_LINEINDEX AND "See also"
-
- When using this message under Win32s (1.30a and above) with
- the RichEdit control, the parameters the message takes are:
-
- wParam = 0;
- lParam = &em32s;
-
- Where em32s is a structure defined as:
-
- struct EM32S {
- DWORD wParam;
- DWORD lParam;
- };
-
- The documented wParam and lParam values are stored in the
- EM32S structure.
-
- Submitted by Larry Widing.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #163
- TYPE: Win32
- TOPIC: EM_LINELENGTH
- KEYWORD: EM_LINELENGTH AND "See also"
-
- When using this message under Win32s (1.30a and above) with
- the RichEdit control, the parameters the message takes are:
-
- wParam = 0;
- lParam = &em32s;
-
- Where em32s is a structure defined as:
-
- struct EM32S {
- DWORD wParam;
- DWORD lParam;
- };
-
- The documented wParam and lParam values are stored in the
- EM32S structure.
-
- Submitted by Larry Widing.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #163
- TYPE: Win32
- TOPIC: EM_LINESCROLL
- KEYWORD: EM_LINESCROLL AND "See also"
-
- When using this message under Win32s (1.30a and above) with the RichEdit
- control, the parameters the message takes are:
-
- wParam = 0;
- lParam = &em32s;
-
- Where em32s is a structure defined as:
-
- struct EM32S {
- DWORD wParam;
- DWORD lParam;
- };
-
- The documented wParam and lParam values are stored in the EM32S structure.
-
- Submitted by Larry Widing.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #164
- TYPE: Win32
- TOPIC: EDITSTREAM
- KEYWORD: EDITSTREAM AND "See also"
-
- The return value from this function is incorrectly
- documented. The return value from the EditStreamCallback is
- interpreted as an SCODE - you should return 0 to indicate
- success or an error code otherwise (both while reading and
- writing).
-
- Reference: MSDN KB article Q136810
-
- Submitted by Donald Munro.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #165
- TYPE: Win16
- TOPIC: GetNextDlgGroupItem
- KEYWORD: GetNextDlgGroupItem
-
- The Win16 SDK fails to mention that this function ignores
- controls that are part of the group but are disabled. The
- documentation has been corrected in Win32.
-
- If you use MFC, check out Annotation #166 (DDX_Radio) for
- this bug's repercussions.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #166
- TYPE: MFC
- TOPIC: DDX_Radio
- KEYWORD: DDX_Radio
-
- DDX_Radio internally uses GetNextDlgGroupItem (see SDK
- annotation #165) and therefore ignores disabled
- radio-buttons. This could causes 2 radio buttons in the
- same group to be selected, if a disabled radio-button is
- selected. Generally, you are better off not using this
- function if you are going to enable/disable radio-buttons.
- Use the Windows SDK functions instead. This applies to MFC
- 1.x and 2.x.
-
- Reference: MSDN KB Q114980
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #167
- TYPE: Win32
- TOPIC: CreatePen
- KEYWORD: CreatePen AND "See also"
-
- If you specify a width greater than 1 for one of the the
- following styles - PS_DASH, PS_DOT, PS_DASHDOT,
- PS_DASHDOTDOT, CreatePen returns a pen with the specified
- width but with the PS_SOLID style.
-
- Submitted by Muthuvale Shanmugam.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #168
- TYPE: Win32
- TOPIC: WindowFromPoint
- KEYWORD: WindowFromPoint AND "See also"
-
- If given a point over a static control, WindowFromPoint()
- returns the handle of the window "under" the static text control.
-
- Submitted by Muthuvale Shanmugam.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #169
- TYPE: Win32
- TOPIC: TranslateMessage
- KEYWORD: TranslateMessage AND "See also"
-
- Though the documentation mentions that it returns TRUE only
- if it translates message, it actually returns TRUE for all
- WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN and WM_SYSKEYUP
- messages. This behaviour is consistent with Windows 3.1
-
- Reference: MSDN KB Q137231
-
-
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #170
- TYPE: Win32
- TOPIC: LoadLibrary
- KEYWORD: LoadLibrary AND "See also"
-
- When writing code for a Win32 DLL, you may be tempted to
- use declare thread-local variables using Windows-specific
- keywords like this:
-
- __declspec(thread) int ThisThreadStatus;
-
- If you do, however, then the resulting DLL can only be
- loaded implicitly (by linking with an import library).
- If any program tries to use LoadLibrary() or LoadLibraryEx()
- to load such a DLL, the call will fail and GetLastError()
- will report a code of 1114L (DLL initialization failed),
- even though your DLL's entry point never gets called.
-
- The only work around is to simply not use __declspec(thread)
- in your DLL. Either use the TlsXxxx() functions to allocate
- thread-local storage, or use your own algorithm for associating
- data with thread handles.
-
-
- ----------------------------------------------------------------------
-
-
- WDJ SDK Annotation #171
- TYPE: Win32
- TOPIC: GetLastError
- KEYWORD: GetLastError AND "See also" NOT MAPIERROR
-
- Some versions of the documentation for GetLastError() state
- that a listing of the error codes is found in WINNT.H. The
- list of error codes is actually found in the file
- WINERROR.H.
-
- Submitted by Katy Mulvey.
-
-
- ----------------------------------------------------------------------
-
-
- WDJ SDK Annotation #172
- TYPE: Win32
- TOPIC: WaitForMultipleObjects
- KEYWORD: WaitForMultipleObjects AND "See also"
-
- The Windows 95 implementation of this function
- has a bug (see the reference for a complete
- explanation). If the same thread claims a mutex
- more than once, then a second thread calls
- WaitForMultipleObjects() to wait on that mutex and at
- least one other object, WaitForMultipleObjects() will
- incorrectly consider the mutex free when the other
- objects being waited on become signaled.
-
- Reference: p. 44, December 1996 Windows Developer's Journal
-
-
-
-
- ----------------------------------------------------------------------
-
-
- WDJ SDK Annotation #173
- TYPE: Win32
- TOPIC: TBBUTTON
- KEYWORD: TBBUTTON AND "See also"
-
- The documentation incorrectly claims that for
- separators (fsStyle equal to TBSTYLE_SEP), the
- idCommand field must be zero. In fact, you can
- assign toolbar separators a non-zero ID. In fact,
- it is important to assign unique IDs to separators
- if they have non-default widths so the customization
- features will work properly. Also, it's a common
- technique to use a "fat" separator as a placeholder
- for a control (such as a drop-down listbox) that you
- want to appear on the toolbox. You will need to
- assign such separators a non-zero ID so that you
- can locate the correct position for the control.
-
-
- Reference: p. 45, November 1996 Windows Developer's Journal
-
-
-
-
- ----------------------------------------------------------------------
-
-
-
-
- WDJ SDK Annotation #174
- TYPE: Win32
- TOPIC: WM_GETDLGCODE
- KEYWORD: WM_GETDLGCODE AND "See also"
-
-
- If a 32-bit control returns DLGC_HASSETSEL, Windows 95 will not send a
- EM_SETSEL message when the control gets the focus. Instead, Windows 95
- sends the control a message with the same value as the 16-bit EM_SETSEL
- (0x401) with 16-bit style parameters. Under Windows NT, your control
- will get the normal 32-bit EM_SETSEL message.
-
- Note: Under Win32, the EM_ messages start at 0xB0 and not at WM_USER
- (0x400) as they did in Win16.
-
- Submitted by Robert Mashlan.
-
-
- ------------------------------------------------------------------------
-
-
- WDJ SDK Annotation #175
- TYPE: Win32
- TOPIC: GetRegionData
- KEYWORD: GetRegionData AND "See also"
-
- The documentation for the return value is incorrect. If the
- function succeeds and dwCount specifies an adequate number
- of bytes, the return value is always dwCount. If the
- function fails or if dwCount specifies less than adequate
- number of bytes, the return value is 0.
-
- Submitted by Peter C. Jahans.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #175
- TYPE: MFC
- TOPIC: CRgn::GetRegionData
- KEYWORD: CRgn::GetRegionData
-
- The documentation for the return value is incorrect. If the
- function succeeds and dwCount specifies an adequate number
- of bytes, the return value is always dwCount. If the
- function fails or if dwCount specifies less than adequate
- number of bytes, the return value is 0 (ERROR).
-
- Submitted by Peter C. Jahans.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #176
- TYPE: Win32
- TOPIC: DrawFocusRect
- KEYWORD: DrawFocusRect AND "See also"
-
- DrawFocusRect() works only in MM_TEXT mode. In other
- modes, this function does not draw the focus rectangle
- correctly, but it does NOT return error values!
-
- Submitted by Jon-David Wiesman.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #176
- TYPE: MFC
- TOPIC: CDC::DrawFocusRect
- KEYWORD: CDC::DrawFocusRect
-
- CDC::DrawFocusRect() works only in MM_TEXT mode. In other
- modes, this function does not draw the focus rectangle
- correctly, but it does NOT return error values!
-
- Submitted by Jon-David Wiesman.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #177
- TYPE: Win32
- TOPIC: FSCTL_DISMOUNT_VOLUME
- KEYWORD: FSCTL_DISMOUNT_VOLUME AND "See also"
-
- The SDK documentation for this function mentions "If the
- specified volume is locked, the operation fails." This is
- incorrect. It should actually read "If the specified volume
- is locked by another process, the operation fails." You must
- do an FSCTL_LOCK_VOLUME before you can do an
- FSCTL_DISMOUNT_VOLUME.
-
- Also, in the sequence of events for reformatting FAT to NTFS
- as described in the same article, steps 4 and 5 must be
- switched - you need to dismount the volume before you unlock
- the volume.
-
- Submitted by Jeffrey S. Goldner.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #178
- TYPE: Win32
- TOPIC: CreateProcess
- KEYWORD: CreateProcess AND "See also"
-
- If you call CreateProcess() with a dwCreationFlags value
- which includes DEBUG_PROCESS, the call will fail under Win95
- when the debugee is a 16-bit app.
-
- Submitted by Marc Cousineau.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #179
- TYPE: Win32
- TOPIC: WM_ACTIVATE
- KEYWORD: WM_ACTIVATE AND "See also"
-
- The documentation states that the message is sent first to
- the top-level window being deactivated and then to the
- window being activated. This is incorrect in Win32. In
- Win32, activation is asynchronous - the activating
- application becomes active immediately and the messages to
- the deactivating application occur later.
-
- Reference: MSDN KB Article Q135785
-
- Submitted by V.Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #179
- TYPE: MFC
- TOPIC: CWnd::OnActivate
- KEYWORD: CWnd::OnActivate
-
- The documentation states that first OnActivate() is called
- for the main window being deactivated, and then for the main
- window being activated This is incorrect in Win32. In
- Win32, activation is asynchronous - the activating
- application becomes immediately and the messages to the
- deactivating application occur later.
-
- Reference: MSDN KB Article Q135785
-
- Submitted by V.Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #180
- TYPE: Win32
- TOPIC: DRAWITEMSTRUCT
- KEYWORD: DRAWITEMSTRUCT AND "See also"
-
- Listviews always set the itemAction member to
- ODA_DRAWENTIRE. You need to check the itemState member to
- check if the focus or selection needs to be updated.
-
- Reference: MSDN KB Article Q131788
-
- Submitted by V.Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #181
- TYPE: MFC 4.2
- TOPIC: CInternetSession::ServiceTypeFromHandle
- KEYWORD: CInternetSession::ServiceTypeFromHandle
-
- The on-line help states
- CInternetSession::ServiceTypeFromHandle() returns the type
- of service given the internet handle. Although this
- function is declared in afxinet.h, it is not defined
- anywhere. Using this function will cause your program to
- fail at link time.
-
- Submitted by Mario Contestabile.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #182
- TYPE: MFC 4.2
- TOPIC: CHttpFile::QueryInfo
- KEYWORD: CHttpFile::QueryInfo
-
- The documentation for CHttpFile::QueryInfo() erroneously states some of
- the possible values for lpdwIndex and dwIndex:
-
- HTTP_QUERY_LANGUAGE is actually HTTP_QUERY_CONTENT_LANGUAGE
- HTTP_QUERY_ALLOWED_METHODS is actually HTTP_QUERY_ALLOW
- HTTP_QUERY_PUBLIC_METHODS is actually HTTP_QUERY_PUBLIC
-
- (All #defines in wininet.h)
-
- Submitted by Mario Contestabile.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #183
- TYPE: MFC 4.x
- TOPIC: COleDateTime::GetYear
- KEYWORD: COleDateTime::GetYear
-
- If the status of this COleDateTime object is not valid, the
- return value is AFX_OLE_DATETIME_ERROR and not
- AFX_DATETIME_ERROR as documented. This affects the following
- member functions: GetYear(), GetMonth(), GetDay(), GetHour(),
- GetMinute(), GetSecond(), GetDayOfWeek(), and GetDayOfYear().
-
-
- Submitted by Mario Contestabile.
-
-
- ----------------------------------------------------------------------
-
-
- WDJ SDK Annotation #184
- TYPE: Win32
- TOPIC: ScrollWindowEx
- KEYWORD: ScrollWindowEx AND "See also"
-
- If the prcClip parameter is NULL, no clipping is performed on the
- scroll rectangle.
-
- Submitted by V. Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #185
- TYPE: Win32
- TOPIC: WM_CONTEXTMENU
- KEYWORD: WM_CONTEXTMENU AND "See also"
-
- If the user uses the keyboard shortcut (Shift-F10 or the special
- key on a Microsoft keyboard) to activate the context menu, the
- xPos and yPos parameters are -1, -1.
-
- Submitted by Katy Mulvey.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #186
- TYPE: Win32
- TOPIC: GetLastError
- KEYWORD: GetLastError AND "return values" AND parameters NOT S_OK
-
- The Win32 Programmer's Reference documentation for
- GetLastError() incorrectly states that a listing of the
- error codes is found in WINNT.H. It is actually found in
- the file WINERROR.H
-
- Note: This error has been corrected in the Jan 97 MSDN.
-
- Submitted by Katy Mulvey.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #187
- TYPE: Win32
- TOPIC: CreateWindowEx
- KEYWORD: CreateWindowEx AND "See also"
-
- The documentation does not mention that you can call GetLastError
- to get extended error information if the function fails.
-
- Submitted by V. Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #188
- TYPE: Win32
- TOPIC: WM_SYSCOMMAND
- KEYWORD: WM_SYSCOMMAND AND "See also"
-
- If the wParam is SC_KEYMENU, the lParam contains the
- character code of the key used in combination with the Alt
- key to display the popup menu. For example, pressing Alt+F
- to display the File popup will cause a WM_SYSCOMMAND with
- wParam equal to SC_KEYMENU and lParam equal to 'f'.
-
- Reference: MSDN Article ID Q92527.
-
- Submitted by V. Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #189
- TYPE: Win32
- TOPIC: CreateWindow
- KEYWORD: CreateWindow AND "See also"
-
- For creating static controls with the SS_ICON style, you
- need to specify the icon name in the lpWindowName parameter.
- However, if you have an icon resource identified with a
- numeric id (instead of a string), you need to specify #xxx
- (where xxx is the numeric identifier for the ICON resource)
- in the lpWindowName parameter. You should not use the
- MAKEINTRESOURCE macro.
-
- Submitted by V. Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #189
- TYPE: Win32
- TOPIC: CreateWindowEx
- KEYWORD: CreateWindowEx AND "See also"
-
- For creating static controls with the SS_ICON style, you
- need to specify the icon name in the lpWindowName parameter.
- However, if you have an icon resource identified with a
- numeric id (instead of a string), you need to specify #xxx
- (where xxx is the numeric identifier for the ICON resource)
- in the lpWindowName parameter. You should not use the
- MAKEINTRESOURCE macro.
-
- Submitted by V. Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #190
- TYPE: Win32
- TOPIC: WM_GETTEXT
- KEYWORD: WM_GETTEXT AND "See also"
-
- In Win32, you cannot send the WM_SETTEXT to a static control
- with the SS_ICON style to set the icon. Therefore, you
- should not use the WM_GETTEXT message to retrieve the icon
- handle of static controls with the SS_ICON style. Use the
- STM_SETICON and STM_GETICON messages instead.
-
- Submitted by V. Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #191
- TYPE: Win32
- TOPIC: RegisterHotKey
- KEYWORD: RegisterHotKey AND "See also"
-
- If you want to disable task switching under Win32, you can
- do so by registering hot keys for Ctrl+Esc and Alt+Tab.
-
- Reference: MSDN Article ID Q125614
- Submitted by V. Ramachandran.
-
- ----------------------------------------------------------------------
-
- WDJ SDK Annotation #192
- TYPE: Win32
- TOPIC: CreateFile
- KEYWORD: CreateFile AND "See also"
-
- Under Windows NT, when CreateFile is used with the
- dwCreationDistribution parameter equal to CREATE_ALWAYS,
- the call fails if the file exists and is hidden.
- GetLastError() returns ERROR_ACCESS_DENIED. However, the
- call succeeds under Windows 95 creating a new file that is
- not hidden.
-
- Submitted by Abdul Nizar.
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #192
- TYPE: MFC 4.x
- TOPIC: CFile::Open
- KEYWORD: CFile::Open
-
- Under Windows NT, if the nOpenFlags parameter is ORed with
- CFile::modeCreate and not ORed with CFile::modeNoTruncate,
- CFile::Open fails if the file exists and is hidden. However,
- the call succeeds under Windows 95 creating a new file that
- is not hidden.
-
- Submitted by Abdul Nizar.
-
-
- ----------------------------------------------------------------------
-
- WDJ MFC Annotation #193
- TYPE: MFC
- TOPIC: CListCtrl::SetColumnWidth
- KEYWORD: CListCtrl::SetColumnWidth
-
- The cx parameter is the new width of the column in listview
- coordinates, or one of the following
-
- LVSCW_AUTOSIZE Automatically sizes the column.
- LVSCW_AUTOSIZE_USEHEADER Automatically sizes the column to
- fit the header text
-
- Submitted by Ramon de Klein.
-
- ----------------------------------------------------------------------
-
-
-
- WDJ SDK Annotation #194
- TYPE: Win32
- TOPIC: PeekMessage
- KEYWORD: PeekMessage AND "See also"
-
- PeekMessage will always retrieve WM_QUIT messages,
- irrespective of the setting of uMsgFilterMin and
- uMsgFilterMax.
-
- Submitted by Graham King.
-
- ----------------------------------------------------------
-
- WDJ MFC Annotation #195
- TYPE: MFC 4.x
- TOPIC: CWinApp::OnIdle
- KEYWORD: CWinApp::OnIdle
-
- If you do not want OnIdle to be called whenever a
- message is retrieved from the message queue, you can
- override the IsIdleMessage. If an application has set
- a very short timer or if the system is sending the
- undocumented WM_SYSTIMER (0x118) message, then OnIdle
- will be called repeatedly, and degrade performance.
-
- Submitted by Adrian Pybus.
-
- ----------------------------------------------------------
-
- WDJ MFC Annotation #196
- TYPE: MFC 4.x
- TOPIC: CImageList::Create
- KEYWORD: CImageList::Create
-
- The documentation for argument bMask is incorrect. In
- fact this value is a UINT bitmask, and accepts
- combinations of the following values:
-
- ILC_MASK 0x0001 // ImageList has a mask
- ILC_COLORDDB 0x00FE // use device dependent bitmap
- ILC_COLOR4 0x0004 // use 4bpp DIBSection
- ILC_COLOR8 0x0008 // use 8bpp DIBSection
- ILC_COLOR16 0x0010 // use 16bpp DIBSection
- ILC_COLOR24 0x0018 // use 24bpp DIBSection
- ILC_COLOR32 0x0020 // use 32bpp DIBSection
- ILC_PALETTE 0x0800 // use palette with image list
-
- Refer to ImageList_Create for more information about
- these flags.
-
- Submitted by Frank Brown.
-
- ----------------------------------------------------------
-
- WDJ SDK Annotation #197
- TYPE: Win32
- TOPIC: NetServerDiskEnum
- KEYWORD: NetServerDiskEnum AND "See also"
-
- The Win32 documentation for NetServerDiskEnum is
- incorrect on the following four points:
-
- 1. The 'level' parameter has to be 0, and not 100 as documented.
- 2. The function returns the enumerated disks as an array
- of 3 character Unicode strings pointed to by the bufptr
- parameter.
- 3. NetServerDiskEnum fails if its "servername" argument
- is a Win95 computer.
- 4. This function is available only on NT (Unicode only).
- However, the header file (lmserver.h) declarations
- specify LPTSTR for string parameters - they actually
- require LPWSTR strings.
-
- You would call this function as follows:
-
- WCHAR (*pDrives)[3] = NULL;
- ret = NetServerDiskEnum(
- (LPTSTR)servername,
- 0,
- (LPBYTE *)(&pDrives),
- 0,
- &entriesRead,
- &totalEntries,
- &resumeHandle ) ;
-
- Submitted by Aaron J Margosis.
-
- ----------------------------------------------------------
-
-
- WDJ SDK Annotation #198
- TYPE: Win32
- TOPIC: StringFromGUID2
- KEYWORD: StringFromGUID2 AND "See also"
-
- The string received is enclosed by curly braces like
- the following sample and not square braces as indicated
- in the documentation.
- {c200e360-38c5-11ce-ae62-08002b2b79ef}
-
- Submitted by V.Ramachandran.
-
- ----------------------------------------------------------
-
-
- WDJ SDK Annotation #199
- TYPE: Win32
- TOPIC: GetUpdateRect
- KEYWORD: GetUpdateRect AND "See also"
-
- If the window was created with the CS_OWNDC style,
- GetUpdateRect always retrieves the rectangle in
- logical coordinates irrespective of the mapping mode.
-
- Submitted by V.Ramachandran.
-
- ----------------------------------------------------------
-
- WDJ SDK Annotation #200
- TYPE: Win32
- TOPIC: BrowseCallbackProc
- KEYWORD: BrowseCallbackProc AND "See also"
-
- The documentation errs in the parameters for the
- notifications:
- BFFM_INITIALIZED: lParam is 0, lpData is the application
- defined value specified in the BROWSEINFO structure.
- BFFM_SELCHANGED: lParam points to the item identifier list
- for the newly selected item, lpData is the application
- defined value specified in the BROWSEINFO structure.
-
- For the BFFM_ENABLEOK message, the lParam should be 0
- for disabling, and non-zero for enabling the OK button,
- and not the wParam as documented.
-
- Submitted by John Bates.
-
- ----------------------------------------------------------
-
- WDJ SDK Annotation #201
- TYPE: Win32
- TOPIC: SHBrowseForFolder
- KEYWORD: SHBrowseForFolder AND "See also"
-
- If the BIF_RETURNONLYFSDIRS flag is specified, the
- OK button stays enabled for a "\\computer" item, not
- just the "\\computer\share" and directory items.
- SHGetPathFromIDList() will fail if you pass it the
- LPITEMIDLIST returned from SHBrowseForFolder when you
- select just a computer name.
-
- Submitted by John Bates.
-
- ----------------------------------------------------------
-
- WDJ SDK Annotation #202
- TYPE: Win32
- TOPIC: MoveWindow
- KEYWORD: MoveWindow AND "See also"
-
- If the bRepaint flag is FALSE, no repainting of any
- kind occurs. The Remarks section is incorrect in saying
- that a WM_PAINT message is placed in the message queue.
-
- Submitted by V.Ramachandran.
-
- ----------------------------------------------------------
-
- WDJ SDK Annotation #203
- TYPE: Win32
- TOPIC: WideCharToMultiByte
- KEYWORD: WideCharToMultiByte AND "See also"
-
- If the function succeeds, the return value is equal to
- the string length plus the terminating NULL character.
- If cchMultiByte specifies a value less than necessary,
- the function returns 0, and GetLastError returns
- ERROR_INSUFFICIENT_BUFFER. However, cchMultiByte
- characters are copied to the buffer pointed to by
- lpMultiByteStr.
-
- ----------------------------------------------------------
-
-